70#include "llvm/IR/IntrinsicsPowerPC.h"
105#define DEBUG_TYPE "ppc-lowering"
127 cl::desc(
"disable vector permute decomposition"),
131 "disable-auto-paired-vec-st",
132 cl::desc(
"disable automatically generated 32byte paired vector stores"),
137 cl::desc(
"Set minimum number of entries to use a jump table on PPC"));
142 "Number of shuffles lowered to a VPERM or XXPERM");
143STATISTIC(NumDynamicAllocaProbed,
"Number of dynamic stack allocation probed");
166 initializeAddrModeMap();
169 bool isPPC64 = Subtarget.
isPPC64();
178 if (!Subtarget.hasEFPU2())
203 if (Subtarget.isISA3_0()) {
233 if (!Subtarget.hasSPE()) {
241 const MVT ScalarIntVTs[] = { MVT::i32, MVT::i64 };
242 for (
MVT VT : ScalarIntVTs) {
249 if (Subtarget.useCRBits()) {
252 if (isPPC64 || Subtarget.hasFPCVT()) {
255 isPPC64 ? MVT::i64 : MVT::i32);
258 isPPC64 ? MVT::i64 : MVT::i32);
262 isPPC64 ? MVT::i64 : MVT::i32);
265 isPPC64 ? MVT::i64 : MVT::i32);
269 isPPC64 ? MVT::i64 : MVT::i32);
272 isPPC64 ? MVT::i64 : MVT::i32);
276 isPPC64 ? MVT::i64 : MVT::i32);
279 isPPC64 ? MVT::i64 : MVT::i32);
326 if (Subtarget.isISA3_0()) {
361 if (!Subtarget.hasSPE()) {
366 if (Subtarget.hasVSX()) {
371 if (Subtarget.hasFSQRT()) {
376 if (Subtarget.hasFPRND()) {
417 if (Subtarget.hasSPE()) {
425 if (Subtarget.hasSPE())
431 if (!Subtarget.hasFSQRT() &&
432 !(
TM.Options.UnsafeFPMath && Subtarget.hasFRSQRTE() &&
436 if (!Subtarget.hasFSQRT() &&
437 !(
TM.Options.UnsafeFPMath && Subtarget.hasFRSQRTES() &&
438 Subtarget.hasFRES()))
441 if (Subtarget.hasFCPSGN()) {
449 if (Subtarget.hasFPRND()) {
463 if (Subtarget.isISA3_1()) {
474 if (Subtarget.isISA3_0()) {
494 if (!Subtarget.useCRBits()) {
507 if (!Subtarget.useCRBits())
510 if (Subtarget.hasFPU()) {
521 if (!Subtarget.useCRBits())
526 if (Subtarget.hasSPE()) {
550 if (Subtarget.hasDirectMove() && isPPC64) {
555 if (
TM.Options.UnsafeFPMath) {
658 if (Subtarget.hasSPE()) {
680 if (Subtarget.has64BitSupport()) {
695 if (Subtarget.hasLFIWAX() || Subtarget.
isPPC64()) {
701 if (Subtarget.hasSPE()) {
711 if (Subtarget.hasFPCVT()) {
712 if (Subtarget.has64BitSupport()) {
733 if (Subtarget.use64BitRegs()) {
751 if (Subtarget.has64BitSupport()) {
758 if (Subtarget.hasVSX()) {
765 if (Subtarget.hasAltivec()) {
766 for (
MVT VT : { MVT::v16i8, MVT::v8i16, MVT::v4i32 }) {
781 if (VT.getSizeInBits() <= 128 && VT.getScalarSizeInBits() <= 64) {
794 if (Subtarget.hasVSX()) {
800 if (Subtarget.hasP8Altivec() && (VT.SimpleTy != MVT::v1i128)) {
810 if (Subtarget.hasP9Altivec() && (VT.SimpleTy != MVT::v1i128))
884 if (!Subtarget.hasP8Vector()) {
926 if (Subtarget.hasAltivec())
927 for (
auto VT : {MVT::v4i32, MVT::v8i16, MVT::v16i8})
930 if (Subtarget.hasP8Altivec())
941 if (Subtarget.hasVSX()) {
947 if (Subtarget.hasP8Altivec())
952 if (Subtarget.isISA3_1()) {
990 if (Subtarget.hasVSX()) {
993 if (Subtarget.hasP8Vector()) {
997 if (Subtarget.hasDirectMove() && isPPC64) {
1011 if (
TM.Options.UnsafeFPMath) {
1048 if (Subtarget.hasP8Vector())
1057 if (Subtarget.hasP8Altivec()) {
1084 if (Subtarget.isISA3_1())
1187 if (Subtarget.hasP8Altivec()) {
1192 if (Subtarget.hasP9Vector()) {
1197 if (Subtarget.useCRBits()) {
1256 }
else if (Subtarget.hasVSX()) {
1281 for (
MVT VT : {MVT::f32, MVT::f64}) {
1300 if (Subtarget.hasP9Altivec()) {
1301 if (Subtarget.isISA3_1()) {
1324 if (Subtarget.hasP10Vector()) {
1329 if (Subtarget.pairedVectorMemops()) {
1334 if (Subtarget.hasMMA()) {
1335 if (Subtarget.isISAFuture())
1344 if (Subtarget.has64BitSupport())
1347 if (Subtarget.isISA3_1())
1365 if (Subtarget.hasAltivec()) {
1392 if (Subtarget.hasFPCVT())
1395 if (Subtarget.useCRBits())
1404 if (Subtarget.useCRBits()) {
1435 setLibcallName(RTLIB::MEMCPY, isPPC64 ?
"___memmove64" :
"___memmove");
1436 setLibcallName(RTLIB::MEMMOVE, isPPC64 ?
"___memmove64" :
"___memmove");
1437 setLibcallName(RTLIB::MEMSET, isPPC64 ?
"___memset64" :
"___memset");
1438 setLibcallName(RTLIB::BZERO, isPPC64 ?
"___bzero64" :
"___bzero");
1443 if (Subtarget.useCRBits()) {
1546void PPCTargetLowering::initializeAddrModeMap() {
1597 if (MaxAlign == MaxMaxAlign)
1599 if (
VectorType *VTy = dyn_cast<VectorType>(Ty)) {
1600 if (MaxMaxAlign >= 32 &&
1601 VTy->getPrimitiveSizeInBits().getFixedValue() >= 256)
1602 MaxAlign =
Align(32);
1603 else if (VTy->getPrimitiveSizeInBits().getFixedValue() >= 128 &&
1605 MaxAlign =
Align(16);
1606 }
else if (
ArrayType *ATy = dyn_cast<ArrayType>(Ty)) {
1609 if (EltAlign > MaxAlign)
1610 MaxAlign = EltAlign;
1611 }
else if (
StructType *STy = dyn_cast<StructType>(Ty)) {
1612 for (
auto *EltTy : STy->elements()) {
1615 if (EltAlign > MaxAlign)
1616 MaxAlign = EltAlign;
1617 if (MaxAlign == MaxMaxAlign)
1630 if (Subtarget.hasAltivec())
1632 return Alignment.
value();
1640 return Subtarget.hasSPE();
1648 Type *VectorTy,
unsigned ElemSizeInBits,
unsigned &
Index)
const {
1649 if (!Subtarget.
isPPC64() || !Subtarget.hasVSX())
1652 if (
auto *VTy = dyn_cast<VectorType>(VectorTy)) {
1653 if (VTy->getScalarType()->isIntegerTy()) {
1655 if (ElemSizeInBits == 32) {
1659 if (ElemSizeInBits == 64) {
1685 return "PPCISD::FTSQRT";
1687 return "PPCISD::FSQRT";
1692 return "PPCISD::XXSPLTI_SP_TO_DP";
1694 return "PPCISD::XXSPLTI32DX";
1698 return "PPCISD::XXPERM";
1718 return "PPCISD::CALL_RM";
1720 return "PPCISD::CALL_NOP_RM";
1722 return "PPCISD::CALL_NOTOC_RM";
1727 return "PPCISD::BCTRL_RM";
1729 return "PPCISD::BCTRL_LOAD_TOC_RM";
1741 return "PPCISD::SCALAR_TO_VECTOR_PERMUTED";
1743 return "PPCISD::ANDI_rec_1_EQ_BIT";
1745 return "PPCISD::ANDI_rec_1_GT_BIT";
1760 return "PPCISD::ST_VSR_SCAL_INT";
1787 return "PPCISD::PADDI_DTPREL";
1803 return "PPCISD::TLS_DYNAMIC_MAT_PCREL_ADDR";
1805 return "PPCISD::TLS_LOCAL_EXEC_MAT_ADDR";
1815 return "PPCISD::STRICT_FADDRTZ";
1817 return "PPCISD::STRICT_FCTIDZ";
1819 return "PPCISD::STRICT_FCTIWZ";
1821 return "PPCISD::STRICT_FCTIDUZ";
1823 return "PPCISD::STRICT_FCTIWUZ";
1825 return "PPCISD::STRICT_FCFID";
1827 return "PPCISD::STRICT_FCFIDU";
1829 return "PPCISD::STRICT_FCFIDS";
1831 return "PPCISD::STRICT_FCFIDUS";
1834 return "PPCISD::STORE_COND";
1842 return Subtarget.useCRBits() ? MVT::i1 : MVT::i32;
1859 return CFP->getValueAPF().isZero();
1863 if (
const ConstantFP *CFP = dyn_cast<ConstantFP>(CP->getConstVal()))
1864 return CFP->getValueAPF().isZero();
1872 return Op < 0 ||
Op == Val;
1884 if (ShuffleKind == 0) {
1887 for (
unsigned i = 0; i != 16; ++i)
1890 }
else if (ShuffleKind == 2) {
1893 for (
unsigned i = 0; i != 16; ++i)
1896 }
else if (ShuffleKind == 1) {
1897 unsigned j = IsLE ? 0 : 1;
1898 for (
unsigned i = 0; i != 8; ++i)
1915 if (ShuffleKind == 0) {
1918 for (
unsigned i = 0; i != 16; i += 2)
1922 }
else if (ShuffleKind == 2) {
1925 for (
unsigned i = 0; i != 16; i += 2)
1929 }
else if (ShuffleKind == 1) {
1930 unsigned j = IsLE ? 0 : 2;
1931 for (
unsigned i = 0; i != 8; i += 2)
1952 if (!Subtarget.hasP8Vector())
1956 if (ShuffleKind == 0) {
1959 for (
unsigned i = 0; i != 16; i += 4)
1965 }
else if (ShuffleKind == 2) {
1968 for (
unsigned i = 0; i != 16; i += 4)
1974 }
else if (ShuffleKind == 1) {
1975 unsigned j = IsLE ? 0 : 4;
1976 for (
unsigned i = 0; i != 8; i += 4)
1993 unsigned LHSStart,
unsigned RHSStart) {
1994 if (
N->getValueType(0) != MVT::v16i8)
1996 assert((UnitSize == 1 || UnitSize == 2 || UnitSize == 4) &&
1997 "Unsupported merge size!");
1999 for (
unsigned i = 0; i != 8/UnitSize; ++i)
2000 for (
unsigned j = 0; j != UnitSize; ++j) {
2002 LHSStart+j+i*UnitSize) ||
2004 RHSStart+j+i*UnitSize))
2019 if (ShuffleKind == 1)
2021 else if (ShuffleKind == 2)
2026 if (ShuffleKind == 1)
2028 else if (ShuffleKind == 0)
2044 if (ShuffleKind == 1)
2046 else if (ShuffleKind == 2)
2051 if (ShuffleKind == 1)
2053 else if (ShuffleKind == 0)
2103 unsigned RHSStartValue) {
2104 if (
N->getValueType(0) != MVT::v16i8)
2107 for (
unsigned i = 0; i < 2; ++i)
2108 for (
unsigned j = 0; j < 4; ++j)
2110 i*RHSStartValue+j+IndexOffset) ||
2112 i*RHSStartValue+j+IndexOffset+8))
2134 unsigned indexOffset = CheckEven ? 4 : 0;
2135 if (ShuffleKind == 1)
2137 else if (ShuffleKind == 2)
2143 unsigned indexOffset = CheckEven ? 0 : 4;
2144 if (ShuffleKind == 1)
2146 else if (ShuffleKind == 0)
2162 if (
N->getValueType(0) != MVT::v16i8)
2169 for (i = 0; i != 16 && SVOp->
getMaskElt(i) < 0; ++i)
2172 if (i == 16)
return -1;
2177 if (ShiftAmt < i)
return -1;
2182 if ((ShuffleKind == 0 && !isLE) || (ShuffleKind == 2 && isLE)) {
2184 for (++i; i != 16; ++i)
2187 }
else if (ShuffleKind == 1) {
2189 for (++i; i != 16; ++i)
2196 ShiftAmt = 16 - ShiftAmt;
2205 EVT VT =
N->getValueType(0);
2206 if (VT == MVT::v2i64 || VT == MVT::v2f64)
2207 return EltSize == 8 &&
N->getMaskElt(0) ==
N->getMaskElt(1);
2210 EltSize <= 8 &&
"Can only handle 1,2,4,8 byte element sizes");
2214 if (
N->getMaskElt(0) % EltSize != 0)
2219 unsigned ElementBase =
N->getMaskElt(0);
2222 if (ElementBase >= 16)
2227 for (
unsigned i = 1; i != EltSize; ++i)
2228 if (
N->getMaskElt(i) < 0 ||
N->getMaskElt(i) != (
int)(i+ElementBase))
2231 for (
unsigned i = EltSize, e = 16; i != e; i += EltSize) {
2232 if (
N->getMaskElt(i) < 0)
continue;
2233 for (
unsigned j = 0; j != EltSize; ++j)
2234 if (
N->getMaskElt(i+j) !=
N->getMaskElt(j))
2251 assert((Width == 2 || Width == 4 || Width == 8 || Width == 16) &&
2252 "Unexpected element width.");
2253 assert((StepLen == 1 || StepLen == -1) &&
"Unexpected element width.");
2255 unsigned NumOfElem = 16 / Width;
2256 unsigned MaskVal[16];
2257 for (
unsigned i = 0; i < NumOfElem; ++i) {
2258 MaskVal[0] =
N->getMaskElt(i * Width);
2259 if ((StepLen == 1) && (MaskVal[0] % Width)) {
2261 }
else if ((StepLen == -1) && ((MaskVal[0] + 1) % Width)) {
2265 for (
unsigned int j = 1; j < Width; ++j) {
2266 MaskVal[j] =
N->getMaskElt(i * Width + j);
2267 if (MaskVal[j] != MaskVal[j-1] + StepLen) {
2277 unsigned &InsertAtByte,
bool &Swap,
bool IsLE) {
2282 unsigned M0 =
N->getMaskElt(0) / 4;
2283 unsigned M1 =
N->getMaskElt(4) / 4;
2284 unsigned M2 =
N->getMaskElt(8) / 4;
2285 unsigned M3 =
N->getMaskElt(12) / 4;
2286 unsigned LittleEndianShifts[] = { 2, 1, 0, 3 };
2287 unsigned BigEndianShifts[] = { 3, 0, 1, 2 };
2292 if ((
M0 > 3 &&
M1 == 1 && M2 == 2 && M3 == 3) ||
2293 (
M0 < 4 &&
M1 == 5 && M2 == 6 && M3 == 7)) {
2294 ShiftElts = IsLE ? LittleEndianShifts[
M0 & 0x3] : BigEndianShifts[
M0 & 0x3];
2295 InsertAtByte = IsLE ? 12 : 0;
2300 if ((
M1 > 3 &&
M0 == 0 && M2 == 2 && M3 == 3) ||
2301 (
M1 < 4 &&
M0 == 4 && M2 == 6 && M3 == 7)) {
2302 ShiftElts = IsLE ? LittleEndianShifts[
M1 & 0x3] : BigEndianShifts[
M1 & 0x3];
2303 InsertAtByte = IsLE ? 8 : 4;
2308 if ((M2 > 3 &&
M0 == 0 &&
M1 == 1 && M3 == 3) ||
2309 (M2 < 4 &&
M0 == 4 &&
M1 == 5 && M3 == 7)) {
2310 ShiftElts = IsLE ? LittleEndianShifts[M2 & 0x3] : BigEndianShifts[M2 & 0x3];
2311 InsertAtByte = IsLE ? 4 : 8;
2316 if ((M3 > 3 &&
M0 == 0 &&
M1 == 1 && M2 == 2) ||
2317 (M3 < 4 &&
M0 == 4 &&
M1 == 5 && M2 == 6)) {
2318 ShiftElts = IsLE ? LittleEndianShifts[M3 & 0x3] : BigEndianShifts[M3 & 0x3];
2319 InsertAtByte = IsLE ? 0 : 12;
2326 if (
N->getOperand(1).isUndef()) {
2329 unsigned XXINSERTWSrcElem = IsLE ? 2 : 1;
2330 if (
M0 == XXINSERTWSrcElem &&
M1 == 1 && M2 == 2 && M3 == 3) {
2331 InsertAtByte = IsLE ? 12 : 0;
2334 if (
M0 == 0 &&
M1 == XXINSERTWSrcElem && M2 == 2 && M3 == 3) {
2335 InsertAtByte = IsLE ? 8 : 4;
2338 if (
M0 == 0 &&
M1 == 1 && M2 == XXINSERTWSrcElem && M3 == 3) {
2339 InsertAtByte = IsLE ? 4 : 8;
2342 if (
M0 == 0 &&
M1 == 1 && M2 == 2 && M3 == XXINSERTWSrcElem) {
2343 InsertAtByte = IsLE ? 0 : 12;
2352 bool &Swap,
bool IsLE) {
2353 assert(
N->getValueType(0) == MVT::v16i8 &&
"Shuffle vector expects v16i8");
2359 unsigned M0 =
N->getMaskElt(0) / 4;
2360 unsigned M1 =
N->getMaskElt(4) / 4;
2361 unsigned M2 =
N->getMaskElt(8) / 4;
2362 unsigned M3 =
N->getMaskElt(12) / 4;
2366 if (
N->getOperand(1).isUndef()) {
2367 assert(
M0 < 4 &&
"Indexing into an undef vector?");
2368 if (
M1 != (
M0 + 1) % 4 || M2 != (
M1 + 1) % 4 || M3 != (M2 + 1) % 4)
2371 ShiftElts = IsLE ? (4 -
M0) % 4 :
M0;
2377 if (
M1 != (
M0 + 1) % 8 || M2 != (
M1 + 1) % 8 || M3 != (M2 + 1) % 8)
2381 if (
M0 == 0 ||
M0 == 7 ||
M0 == 6 ||
M0 == 5) {
2386 ShiftElts = (8 -
M0) % 8;
2387 }
else if (
M0 == 4 ||
M0 == 3 ||
M0 == 2 ||
M0 == 1) {
2392 ShiftElts = (4 -
M0) % 4;
2397 if (
M0 == 0 ||
M0 == 1 ||
M0 == 2 ||
M0 == 3) {
2402 }
else if (
M0 == 4 ||
M0 == 5 ||
M0 == 6 ||
M0 == 7) {
2414 assert(
N->getValueType(0) == MVT::v16i8 &&
"Shuffle vector expects v16i8");
2419 for (
int i = 0; i < 16; i += Width)
2420 if (
N->getMaskElt(i) != i + Width - 1)
2451 bool &Swap,
bool IsLE) {
2452 assert(
N->getValueType(0) == MVT::v16i8 &&
"Shuffle vector expects v16i8");
2458 unsigned M0 =
N->getMaskElt(0) / 8;
2459 unsigned M1 =
N->getMaskElt(8) / 8;
2460 assert(((
M0 |
M1) < 4) &&
"A mask element out of bounds?");
2464 if (
N->getOperand(1).isUndef()) {
2465 if ((
M0 |
M1) < 2) {
2466 DM = IsLE ? (((~M1) & 1) << 1) + ((~
M0) & 1) : (
M0 << 1) + (
M1 & 1);
2474 if (
M0 > 1 &&
M1 < 2) {
2476 }
else if (M0 < 2 && M1 > 1) {
2484 DM = (((~M1) & 1) << 1) + ((~
M0) & 1);
2487 if (M0 < 2 && M1 > 1) {
2489 }
else if (
M0 > 1 &&
M1 < 2) {
2497 DM = (
M0 << 1) + (
M1 & 1);
2512 if (VT == MVT::v2i64 || VT == MVT::v2f64)
2517 return (16 / EltSize) - 1 - (SVOp->
getMaskElt(0) / EltSize);
2533 unsigned EltSize = 16/
N->getNumOperands();
2534 if (EltSize < ByteSize) {
2535 unsigned Multiple = ByteSize/EltSize;
2537 assert(Multiple > 1 && Multiple <= 4 &&
"How can this happen?");
2540 for (
unsigned i = 0, e =
N->getNumOperands(); i != e; ++i) {
2541 if (
N->getOperand(i).isUndef())
continue;
2543 if (!isa<ConstantSDNode>(
N->getOperand(i)))
return SDValue();
2545 if (!UniquedVals[i&(Multiple-1)].getNode())
2546 UniquedVals[i&(Multiple-1)] =
N->getOperand(i);
2547 else if (UniquedVals[i&(Multiple-1)] !=
N->getOperand(i))
2557 bool LeadingZero =
true;
2558 bool LeadingOnes =
true;
2559 for (
unsigned i = 0; i != Multiple-1; ++i) {
2560 if (!UniquedVals[i].getNode())
continue;
2567 if (!UniquedVals[Multiple-1].getNode())
2574 if (!UniquedVals[Multiple-1].getNode())
2576 int Val =cast<ConstantSDNode>(UniquedVals[Multiple-1])->getSExtValue();
2585 for (
unsigned i = 0, e =
N->getNumOperands(); i != e; ++i) {
2586 if (
N->getOperand(i).isUndef())
continue;
2588 OpVal =
N->getOperand(i);
2589 else if (OpVal !=
N->getOperand(i))
2595 unsigned ValSizeInBytes = EltSize;
2598 Value = CN->getZExtValue();
2600 assert(CN->getValueType(0) == MVT::f32 &&
"Only one legal FP vector type!");
2601 Value = llvm::bit_cast<uint32_t>(CN->getValueAPF().convertToFloat());
2607 if (ValSizeInBytes < ByteSize)
return SDValue();
2618 if (MaskVal == 0)
return SDValue();
2621 if (SignExtend32<5>(MaskVal) == MaskVal)
2635 if (!isa<ConstantSDNode>(
N))
2638 Imm = (int16_t)
N->getAsZExtVal();
2639 if (
N->getValueType(0) == MVT::i32)
2640 return Imm == (int32_t)
N->getAsZExtVal();
2642 return Imm == (int64_t)
N->getAsZExtVal();
2660 return (~(LHSKnown.
Zero | RHSKnown.
Zero) == 0);
2669 if (
MemSDNode *Memop = dyn_cast<MemSDNode>(U)) {
2670 if (Memop->getMemoryVT() == MVT::f64) {
2671 Base =
N.getOperand(0);
2684 if (!isa<ConstantSDNode>(
N))
2687 Imm = (int64_t)
N->getAsZExtVal();
2688 return isInt<34>(Imm);
2715 (!EncodingAlignment ||
isAligned(*EncodingAlignment, Imm)))
2720 Base =
N.getOperand(0);
2723 }
else if (
N.getOpcode() ==
ISD::OR) {
2725 (!EncodingAlignment ||
isAligned(*EncodingAlignment, Imm)))
2737 if (~(LHSKnown.
Zero | RHSKnown.
Zero) == 0) {
2738 Base =
N.getOperand(0);
2809 (!EncodingAlignment ||
isAligned(*EncodingAlignment, imm))) {
2815 Base =
N.getOperand(0);
2818 }
else if (
N.getOperand(1).getOpcode() ==
PPCISD::Lo) {
2820 assert(!
N.getOperand(1).getConstantOperandVal(1) &&
2821 "Cannot handle constant offsets yet!");
2822 Disp =
N.getOperand(1).getOperand(0);
2827 Base =
N.getOperand(0);
2830 }
else if (
N.getOpcode() ==
ISD::OR) {
2833 (!EncodingAlignment ||
isAligned(*EncodingAlignment, imm))) {
2843 dyn_cast<FrameIndexSDNode>(
N.getOperand(0))) {
2847 Base =
N.getOperand(0);
2860 (!EncodingAlignment ||
isAligned(*EncodingAlignment, Imm))) {
2863 CN->getValueType(0));
2868 if ((CN->getValueType(0) == MVT::i32 ||
2869 (int64_t)CN->getZExtValue() == (
int)CN->getZExtValue()) &&
2870 (!EncodingAlignment ||
2871 isAligned(*EncodingAlignment, CN->getZExtValue()))) {
2872 int Addr = (int)CN->getZExtValue();
2879 unsigned Opc = CN->
getValueType(0) == MVT::i32 ? PPC::LIS : PPC::LIS8;
2900 if (
N.getValueType() != MVT::i64)
2913 Base =
N.getOperand(0);
2929 Base =
N.getOperand(0);
2962 !
N.getOperand(1).hasOneUse() || !
N.getOperand(0).hasOneUse())) {
2963 Base =
N.getOperand(0);
2976 Ty *PCRelCand = dyn_cast<Ty>(
N);
2988 if (isValidPCRelNode<ConstantPoolSDNode>(
N) ||
2989 isValidPCRelNode<GlobalAddressSDNode>(
N) ||
2990 isValidPCRelNode<JumpTableSDNode>(
N) ||
2991 isValidPCRelNode<BlockAddressSDNode>(
N))
3007 EVT MemVT = LD->getMemoryVT();
3014 if (!ST.hasP8Vector())
3019 if (!ST.hasP9Vector())
3032 if (UI.getUse().get().getResNo() == 0 &&
3054 Ptr = LD->getBasePtr();
3055 VT = LD->getMemoryVT();
3056 Alignment = LD->getAlign();
3057 }
else if (
StoreSDNode *ST = dyn_cast<StoreSDNode>(
N)) {
3058 Ptr = ST->getBasePtr();
3059 VT = ST->getMemoryVT();
3060 Alignment = ST->getAlign();
3083 if (isa<FrameIndexSDNode>(
Base) || isa<RegisterSDNode>(
Base))
3086 SDValue Val = cast<StoreSDNode>(
N)->getValue();
3099 if (VT != MVT::i64) {
3104 if (Alignment <
Align(4))
3114 if (LD->getValueType(0) == MVT::i64 && LD->getMemoryVT() == MVT::i32 &&
3116 isa<ConstantSDNode>(
Offset))
3131 unsigned &HiOpFlags,
unsigned &LoOpFlags,
3173 const bool Is64Bit = Subtarget.
isPPC64();
3174 EVT VT = Is64Bit ? MVT::i64 : MVT::i32;
3188 EVT PtrVT =
Op.getValueType();
3204 return getTOCEntry(DAG,
SDLoc(CP), GA);
3207 unsigned MOHiFlag, MOLoFlag;
3214 return getTOCEntry(DAG,
SDLoc(CP), GA);
3274 EVT PtrVT =
Op.getValueType();
3292 return getTOCEntry(DAG,
SDLoc(JT), GA);
3295 unsigned MOHiFlag, MOLoFlag;
3302 return getTOCEntry(DAG,
SDLoc(GA), GA);
3312 EVT PtrVT =
Op.getValueType();
3331 return getTOCEntry(DAG,
SDLoc(BASDN), GA);
3340 unsigned MOHiFlag, MOLoFlag;
3351 return LowerGlobalTLSAddressAIX(
Op, DAG);
3353 return LowerGlobalTLSAddressLinux(
Op, DAG);
3366 bool Is64Bit = Subtarget.
isPPC64();
3367 bool HasAIXSmallLocalExecTLS = Subtarget.hasAIXSmallLocalExecTLS();
3374 SDValue VariableOffset = getTOCEntry(DAG, dl, VariableOffsetTGA);
3392 if (HasAIXSmallLocalExecTLS && IsTLSLocalExecModel) {
3411 if (HasAIXSmallLocalExecTLS)
3413 "currently only supported on AIX (64-bit mode).");
3429 SDValue VariableOffset = getTOCEntry(DAG, dl, VariableOffsetTGA);
3430 SDValue RegionHandle = getTOCEntry(DAG, dl, RegionHandleTGA);
3448 bool is64bit = Subtarget.
isPPC64();
3495 if (!
TM.isPositionIndependent())
3554 PtrVT, GOTPtr, TGA, TGA);
3556 PtrVT, TLSAddr, TGA);
3565 EVT PtrVT =
Op.getValueType();
3590 return getTOCEntry(DAG,
DL, GA);
3593 unsigned MOHiFlag, MOLoFlag;
3601 return getTOCEntry(DAG,
DL, GA);
3613 bool IsStrict =
Op->isStrictFPOpcode();
3615 cast<CondCodeSDNode>(
Op.getOperand(IsStrict ? 3 : 2))->get();
3619 EVT LHSVT =
LHS.getValueType();
3623 if (LHSVT == MVT::f128) {
3624 assert(!Subtarget.hasP9Vector() &&
3625 "SETCC for f128 is already legal under Power9!");
3636 assert(!IsStrict &&
"Don't know how to handle STRICT_FSETCC!");
3638 if (
Op.getValueType() == MVT::v2i64) {
3641 if (
LHS.getValueType() == MVT::v2i64) {
3649 int ShuffV[] = {1, 0, 3, 2};
3654 dl, MVT::v4i32, Shuff, SetCC32));
3671 if (
C->isAllOnes() ||
C->isZero())
3681 EVT VT =
Op.getValueType();
3690 EVT VT =
Node->getValueType(0);
3694 const Value *SV = cast<SrcValueSDNode>(
Node->getOperand(2))->getValue();
3704 if (VT == MVT::i64) {
3735 InChain = OverflowArea.
getValue(1);
3781 InChain = DAG.
getTruncStore(InChain, dl, OverflowArea, OverflowAreaPtr,
3788 assert(!Subtarget.
isPPC64() &&
"LowerVACOPY is PPC32 only");
3803 return Op.getOperand(0);
3812 "Expecting Inline ASM node.");
3822 if (
Op.getOperand(NumOps - 1).getValueType() == MVT::Glue)
3828 unsigned NumVals =
Flags.getNumOperandRegisters();
3831 switch (
Flags.getKind()) {
3842 for (; NumVals; --NumVals, ++i) {
3843 Register Reg = cast<RegisterSDNode>(
Op.getOperand(i))->getReg();
3844 if (Reg != PPC::LR && Reg != PPC::LR8)
3869 bool isPPC64 = (PtrVT == MVT::i64);
3875 Entry.Ty = IntPtrTy;
3876 Entry.Node = Trmp;
Args.push_back(Entry);
3879 Entry.Node = DAG.
getConstant(isPPC64 ? 48 : 40, dl,
3880 isPPC64 ? MVT::i64 : MVT::i32);
3881 Args.push_back(Entry);
3883 Entry.Node = FPtr;
Args.push_back(Entry);
3884 Entry.Node = Nest;
Args.push_back(Entry);
3888 CLI.setDebugLoc(dl).setChain(Chain).setLibCallee(
3892 std::pair<SDValue, SDValue> CallResult =
LowerCallTo(CLI);
3893 return CallResult.second;
3907 const Value *SV = cast<SrcValueSDNode>(
Op.getOperand(2))->getValue();
3908 return DAG.
getStore(
Op.getOperand(0), dl, FR,
Op.getOperand(1),
3943 uint64_t FrameOffset = PtrVT.getSizeInBits()/8;
3952 const Value *SV = cast<SrcValueSDNode>(
Op.getOperand(2))->getValue();
3967 nextPtr = DAG.
getNode(
ISD::ADD, dl, PtrVT, nextPtr, ConstStackOffset);
3970 SDValue thirdStore = DAG.
getStore(secondStore, dl, StackOffsetFI, nextPtr,
3972 nextOffset += FrameOffset;
3973 nextPtr = DAG.
getNode(
ISD::ADD, dl, PtrVT, nextPtr, ConstFrameOffset);
3976 return DAG.
getStore(thirdStore, dl, FR, nextPtr,
3982static const MCPhysReg FPR[] = {PPC::F1, PPC::F2, PPC::F3, PPC::F4, PPC::F5,
3983 PPC::F6, PPC::F7, PPC::F8, PPC::F9, PPC::F10,
3984 PPC::F11, PPC::F12, PPC::F13};
3989 unsigned PtrByteSize) {
3991 if (Flags.isByVal())
3992 ArgSize = Flags.getByValSize();
3996 if (!Flags.isInConsecutiveRegs())
3997 ArgSize = ((ArgSize + PtrByteSize - 1)/PtrByteSize) * PtrByteSize;
4006 unsigned PtrByteSize) {
4007 Align Alignment(PtrByteSize);
4010 if (ArgVT == MVT::v4f32 || ArgVT == MVT::v4i32 ||
4011 ArgVT == MVT::v8i16 || ArgVT == MVT::v16i8 ||
4012 ArgVT == MVT::v2f64 || ArgVT == MVT::v2i64 ||
4013 ArgVT == MVT::v1i128 || ArgVT == MVT::f128)
4014 Alignment =
Align(16);
4017 if (Flags.isByVal()) {
4018 auto BVAlign = Flags.getNonZeroByValAlign();
4019 if (BVAlign > PtrByteSize) {
4020 if (BVAlign.value() % PtrByteSize != 0)
4022 "ByVal alignment is not a multiple of the pointer size");
4024 Alignment = BVAlign;
4029 if (Flags.isInConsecutiveRegs()) {
4033 if (Flags.isSplit() && OrigVT != MVT::ppcf128)
4047 unsigned PtrByteSize,
unsigned LinkageSize,
4048 unsigned ParamAreaSize,
unsigned &ArgOffset,
4049 unsigned &AvailableFPRs,
4050 unsigned &AvailableVRs) {
4051 bool UseMemory =
false;
4056 ArgOffset =
alignTo(ArgOffset, Alignment);
4059 if (ArgOffset >= LinkageSize + ParamAreaSize)
4064 if (Flags.isInConsecutiveRegsLast())
4065 ArgOffset = ((ArgOffset + PtrByteSize - 1)/PtrByteSize) * PtrByteSize;
4068 if (ArgOffset > LinkageSize + ParamAreaSize)
4073 if (!Flags.isByVal()) {
4074 if (ArgVT == MVT::f32 || ArgVT == MVT::f64)
4075 if (AvailableFPRs > 0) {
4079 if (ArgVT == MVT::v4f32 || ArgVT == MVT::v4i32 ||
4080 ArgVT == MVT::v8i16 || ArgVT == MVT::v16i8 ||
4081 ArgVT == MVT::v2f64 || ArgVT == MVT::v2i64 ||
4082 ArgVT == MVT::v1i128 || ArgVT == MVT::f128)
4083 if (AvailableVRs > 0) {
4095 unsigned NumBytes) {
4099SDValue PPCTargetLowering::LowerFormalArguments(
4104 return LowerFormalArguments_AIX(Chain, CallConv, isVarArg, Ins, dl, DAG,
4107 return LowerFormalArguments_64SVR4(Chain, CallConv, isVarArg, Ins, dl, DAG,
4110 return LowerFormalArguments_32SVR4(Chain, CallConv, isVarArg, Ins, dl, DAG,
4114SDValue PPCTargetLowering::LowerFormalArguments_32SVR4(
4156 const Align PtrAlign(4);
4165 CCInfo.AllocateStack(LinkageSize, PtrAlign);
4167 CCInfo.PreAnalyzeFormalArguments(Ins);
4170 CCInfo.clearWasPPCF128();
4172 for (
unsigned i = 0, e = ArgLocs.
size(); i != e; ++i) {
4185 RC = &PPC::GPRCRegClass;
4188 if (Subtarget.hasP8Vector())
4189 RC = &PPC::VSSRCRegClass;
4190 else if (Subtarget.hasSPE())
4191 RC = &PPC::GPRCRegClass;
4193 RC = &PPC::F4RCRegClass;
4196 if (Subtarget.hasVSX())
4197 RC = &PPC::VSFRCRegClass;
4198 else if (Subtarget.hasSPE())
4200 RC = &PPC::GPRCRegClass;
4202 RC = &PPC::F8RCRegClass;
4207 RC = &PPC::VRRCRegClass;
4210 RC = &PPC::VRRCRegClass;
4214 RC = &PPC::VRRCRegClass;
4221 if (VA.
getLocVT() == MVT::f64 && Subtarget.hasSPE()) {
4222 assert(i + 1 < e &&
"No second half of double precision argument");
4234 ValVT == MVT::i1 ? MVT::i32 : ValVT);
4235 if (ValVT == MVT::i1)
4250 ArgOffset += ArgSize - ObjSize;
4268 CCByValInfo.AllocateStack(CCInfo.getStackSize(), PtrAlign);
4273 unsigned MinReservedArea = CCByValInfo.getStackSize();
4274 MinReservedArea = std::max(MinReservedArea, LinkageSize);
4290 PPC::R3, PPC::R4, PPC::R5, PPC::R6,
4291 PPC::R7, PPC::R8, PPC::R9, PPC::R10,
4293 const unsigned NumGPArgRegs = std::size(GPArgRegs);
4296 PPC::F1, PPC::F2, PPC::F3, PPC::F4, PPC::F5, PPC::F6, PPC::F7,
4299 unsigned NumFPArgRegs = std::size(FPArgRegs);
4308 int Depth = NumGPArgRegs * PtrVT.getSizeInBits()/8 +
4312 PtrVT.getSizeInBits() / 8, CCInfo.getStackSize(),
true));
4321 for (
unsigned GPRIndex = 0; GPRIndex != NumGPArgRegs; ++GPRIndex) {
4325 VReg = MF.
addLiveIn(GPArgRegs[GPRIndex], &PPC::GPRCRegClass);
4340 for (
unsigned FPRIndex = 0; FPRIndex != NumFPArgRegs; ++FPRIndex) {
4344 VReg = MF.
addLiveIn(FPArgRegs[FPRIndex], &PPC::F8RCRegClass);
4357 if (!MemOps.
empty())
4368 const SDLoc &dl)
const {
4372 else if (
Flags.isZExt())
4379SDValue PPCTargetLowering::LowerFormalArguments_64SVR4(
4392 "fastcc not supported on varargs functions");
4398 unsigned PtrByteSize = 8;
4402 PPC::X3, PPC::X4, PPC::X5, PPC::X6,
4403 PPC::X7, PPC::X8, PPC::X9, PPC::X10,
4406 PPC::V2, PPC::V3, PPC::V4, PPC::V5, PPC::V6, PPC::V7, PPC::V8,
4407 PPC::V9, PPC::V10, PPC::V11, PPC::V12, PPC::V13
4410 const unsigned Num_GPR_Regs = std::size(GPR);
4412 const unsigned Num_VR_Regs = std::size(VR);
4420 bool HasParameterArea = !isELFv2ABI || isVarArg;
4421 unsigned ParamAreaSize = Num_GPR_Regs * PtrByteSize;
4422 unsigned NumBytes = LinkageSize;
4423 unsigned AvailableFPRs = Num_FPR_Regs;
4424 unsigned AvailableVRs = Num_VR_Regs;
4425 for (
unsigned i = 0, e =
Ins.size(); i != e; ++i) {
4426 if (Ins[i].
Flags.isNest())
4430 PtrByteSize, LinkageSize, ParamAreaSize,
4431 NumBytes, AvailableFPRs, AvailableVRs))
4432 HasParameterArea =
true;
4439 unsigned ArgOffset = LinkageSize;
4440 unsigned GPR_idx = 0, FPR_idx = 0, VR_idx = 0;
4443 unsigned CurArgIdx = 0;
4444 for (
unsigned ArgNo = 0, e =
Ins.size(); ArgNo != e; ++ArgNo) {
4446 bool needsLoad =
false;
4447 EVT ObjectVT =
Ins[ArgNo].VT;
4448 EVT OrigVT =
Ins[ArgNo].ArgVT;
4450 unsigned ArgSize = ObjSize;
4452 if (Ins[ArgNo].isOrigArg()) {
4453 std::advance(FuncArg, Ins[ArgNo].getOrigArgIndex() - CurArgIdx);
4454 CurArgIdx =
Ins[ArgNo].getOrigArgIndex();
4459 unsigned CurArgOffset;
4461 auto ComputeArgOffset = [&]() {
4465 ArgOffset =
alignTo(ArgOffset, Alignment);
4466 CurArgOffset = ArgOffset;
4473 GPR_idx = (ArgOffset - LinkageSize) / PtrByteSize;
4474 GPR_idx = std::min(GPR_idx, Num_GPR_Regs);
4479 if (
Flags.isByVal()) {
4480 assert(Ins[ArgNo].isOrigArg() &&
"Byval arguments cannot be implicit");
4486 ObjSize =
Flags.getByValSize();
4487 ArgSize = ((ObjSize + PtrByteSize - 1)/PtrByteSize) * PtrByteSize;
4509 if (HasParameterArea ||
4510 ArgSize + ArgOffset > LinkageSize + Num_GPR_Regs * PtrByteSize)
4517 if (ObjSize < PtrByteSize) {
4521 if (!isLittleEndian) {
4527 if (GPR_idx != Num_GPR_Regs) {
4539 ArgOffset += PtrByteSize;
4548 for (
unsigned j = 0;
j < ArgSize;
j += PtrByteSize) {
4549 if (GPR_idx == Num_GPR_Regs)
4560 unsigned StoreSizeInBits = std::min(PtrByteSize, (ObjSize - j)) * 8;
4568 ArgOffset += ArgSize;
4577 if (
Flags.isNest()) {
4582 if (ObjectVT == MVT::i32 || ObjectVT == MVT::i1)
4583 ArgVal = extendArgForPPC64(Flags, ObjectVT, DAG, ArgVal, dl);
4591 if (GPR_idx != Num_GPR_Regs) {
4596 if (ObjectVT == MVT::i32 || ObjectVT == MVT::i1)
4599 ArgVal = extendArgForPPC64(Flags, ObjectVT, DAG, ArgVal, dl);
4605 ArgSize = PtrByteSize;
4616 if (FPR_idx != Num_FPR_Regs) {
4619 if (ObjectVT == MVT::f32)
4621 Subtarget.hasP8Vector()
4622 ? &PPC::VSSRCRegClass
4623 : &PPC::F4RCRegClass);
4626 ? &PPC::VSFRCRegClass
4627 : &PPC::F8RCRegClass);
4642 if (ObjectVT == MVT::f32) {
4643 if ((ArgOffset % PtrByteSize) == (isLittleEndian ? 4 : 0))
4661 ArgSize =
Flags.isInConsecutiveRegs() ? ObjSize : PtrByteSize;
4662 ArgOffset += ArgSize;
4663 if (
Flags.isInConsecutiveRegsLast())
4664 ArgOffset = ((ArgOffset + PtrByteSize - 1)/PtrByteSize) * PtrByteSize;
4678 if (VR_idx != Num_VR_Regs) {
4695 if (ObjSize < ArgSize && !isLittleEndian)
4696 CurArgOffset += ArgSize - ObjSize;
4706 unsigned MinReservedArea;
4707 if (HasParameterArea)
4708 MinReservedArea = std::max(ArgOffset, LinkageSize + 8 * PtrByteSize);
4710 MinReservedArea = LinkageSize;
4727 int Depth = ArgOffset;
4736 for (GPR_idx = (ArgOffset - LinkageSize) / PtrByteSize;
4737 GPR_idx < Num_GPR_Regs; ++GPR_idx) {
4749 if (!MemOps.
empty())
4758 unsigned ParamSize) {
4760 if (!isTailCall)
return 0;
4764 int SPDiff = (int)CallerMinReservedArea - (
int)ParamSize;
4766 if (SPDiff < FI->getTailCallSPDelta())
4782 "PC Relative callers do not have a TOC and cannot share a TOC Base");
4795 if (!
TM.shouldAssumeDSOLocal(*Caller->getParent(), CalleeGV))
4801 const Function *
F = dyn_cast<Function>(CalleeGV);
4802 const GlobalAlias *Alias = dyn_cast<GlobalAlias>(CalleeGV);
4807 F = dyn_cast<Function>(GlobalObj);
4840 if (
TM.getFunctionSections() || CalleeGV->
hasComdat() ||
4841 Caller->hasComdat() || CalleeGV->
getSection() != Caller->getSection())
4843 if (
const auto *
F = dyn_cast<Function>(CalleeGV)) {
4844 if (
F->getSectionPrefix() != Caller->getSectionPrefix())
4856 const unsigned PtrByteSize = 8;
4860 PPC::X3, PPC::X4, PPC::X5, PPC::X6,
4861 PPC::X7, PPC::X8, PPC::X9, PPC::X10,
4864 PPC::V2, PPC::V3, PPC::V4, PPC::V5, PPC::V6, PPC::V7, PPC::V8,
4865 PPC::V9, PPC::V10, PPC::V11, PPC::V12, PPC::V13
4868 const unsigned NumGPRs = std::size(GPR);
4869 const unsigned NumFPRs = 13;
4870 const unsigned NumVRs = std::size(VR);
4871 const unsigned ParamAreaSize = NumGPRs * PtrByteSize;
4873 unsigned NumBytes = LinkageSize;
4874 unsigned AvailableFPRs = NumFPRs;
4875 unsigned AvailableVRs = NumVRs;
4878 if (Param.Flags.isNest())
continue;
4881 LinkageSize, ParamAreaSize, NumBytes,
4882 AvailableFPRs, AvailableVRs))
4893 auto CalleeArgEnd = CB.
arg_end();
4896 for (; CalleeArgIter != CalleeArgEnd; ++CalleeArgIter, ++CallerArgIter) {
4897 const Value* CalleeArg = *CalleeArgIter;
4898 const Value* CallerArg = &(*CallerArgIter);
4899 if (CalleeArg == CallerArg)
4907 isa<UndefValue>(CalleeArg))
4925 if (!isTailCallableCC(CallerCC) || !isTailCallableCC(CalleeCC))
4935bool PPCTargetLowering::IsEligibleForTailCallOptimization_64SVR4(
4940 bool isCalleeExternalSymbol)
const {
4943 if (
DisableSCO && !TailCallOpt)
return false;
4946 if (isVarArg)
return false;
5022bool PPCTargetLowering::IsEligibleForTailCallOptimization(
5056 if (!
C)
return nullptr;
5058 int Addr =
C->getZExtValue();
5059 if ((
Addr & 3) != 0 ||
5065 (
int)
C->getZExtValue() >> 2,
SDLoc(
Op),
5072struct TailCallArgumentInfo {
5077 TailCallArgumentInfo() =
default;
5087 for (
unsigned i = 0, e = TailCallArgs.
size(); i != e; ++i) {
5088 SDValue Arg = TailCallArgs[i].Arg;
5089 SDValue FIN = TailCallArgs[i].FrameIdxOp;
5090 int FI = TailCallArgs[i].FrameIdx;
5093 Chain, dl, Arg, FIN,
5102 int SPDiff,
const SDLoc &dl) {
5108 bool isPPC64 = Subtarget.
isPPC64();
5109 int SlotSize = isPPC64 ? 8 : 4;
5110 int NewRetAddrLoc = SPDiff + FL->getReturnSaveOffset();
5112 NewRetAddrLoc,
true);
5113 EVT VT = isPPC64 ? MVT::i64 : MVT::i32;
5115 Chain = DAG.
getStore(Chain, dl, OldRetAddr, NewRetAddrFrIdx,
5125 SDValue Arg,
int SPDiff,
unsigned ArgOffset,
5127 int Offset = ArgOffset + SPDiff;
5130 EVT VT = isPPC64 ? MVT::i64 : MVT::i32;
5132 TailCallArgumentInfo
Info;
5134 Info.FrameIdxOp = FIN;
5142SDValue PPCTargetLowering::EmitTailCallLoadFPAndRetAddr(
5147 EVT VT = Subtarget.
isPPC64() ? MVT::i64 : MVT::i32;
5148 LROpOut = getReturnAddrFrameIndex(DAG);
5165 return DAG.
getMemcpy(Chain, dl, Dst, Src, SizeNode,
5166 Flags.getNonZeroByValAlign(),
false,
false,
false,
5174 SDValue PtrOff,
int SPDiff,
unsigned ArgOffset,
bool isPPC64,
5197 const SDLoc &dl,
int SPDiff,
unsigned NumBytes,
SDValue LROp,
5207 if (!MemOpChains2.
empty())
5231SDValue PPCTargetLowering::LowerCallResult(
5239 CCRetInfo.AnalyzeCallResult(
5245 for (
unsigned i = 0, e = RVLocs.
size(); i != e; ++i) {
5251 if (Subtarget.hasSPE() && VA.
getLocVT() == MVT::f64) {
5254 Chain =
Lo.getValue(1);
5255 InGlue =
Lo.getValue(2);
5259 Chain =
Hi.getValue(1);
5260 InGlue =
Hi.getValue(2);
5297 auto *
G = dyn_cast<GlobalAddressSDNode>(Callee);
5329 bool IsStrictFPCall =
false) {
5333 unsigned RetOpc = 0;
5358 auto *
G = dyn_cast<GlobalAddressSDNode>(Callee);
5364 if (IsStrictFPCall) {
5395 auto isLocalCallee = [&]() {
5401 !isa_and_nonnull<GlobalIFunc>(GV);
5412 const auto getAIXFuncEntryPointSymbolSDNode = [&](
const GlobalValue *GV) {
5422 auto *
G = dyn_cast<GlobalAddressSDNode>(Callee);
5425 const GlobalValue *GV = cast<GlobalAddressSDNode>(Callee)->getGlobal();
5428 assert(!isa<GlobalIFunc>(GV) &&
"IFunc is not supported on AIX.");
5429 return getAIXFuncEntryPointSymbolSDNode(GV);
5436 const char *SymName = S->getSymbol();
5442 dyn_cast_or_null<Function>(
Mod->getNamedValue(SymName)))
5443 return getAIXFuncEntryPointSymbolSDNode(
F);
5449 const auto getExternalFunctionEntryPointSymbol = [&](
StringRef SymName) {
5457 SymName = getExternalFunctionEntryPointSymbol(SymName)->getName().data();
5464 assert(Callee.getNode() &&
"What no callee?");
5470 "Expected a CALLSEQ_STARTSDNode.");
5487 SDValue MTCTROps[] = {Chain, Callee, Glue};
5488 EVT ReturnTypes[] = {MVT::Other, MVT::Glue};
5529 auto MMOFlags = Subtarget.hasInvariantFunctionDescriptors()
5544 const MVT RegVT = Subtarget.
isPPC64() ? MVT::i64 : MVT::i32;
5548 SDValue LoadFuncPtr = DAG.
getLoad(RegVT, dl, LDChain, Callee, MPI,
5549 Alignment, MMOFlags);
5556 DAG.
getLoad(RegVT, dl, LDChain, AddTOC,
5563 DAG.
getLoad(RegVT, dl, LDChain, AddPtr,
5575 "Nest parameter is not supported on AIX.");
5591 SmallVector<std::pair<unsigned, SDValue>, 8> &RegsToPass,
5594 const bool IsPPC64 = Subtarget.
isPPC64();
5596 const MVT RegVT = IsPPC64 ? MVT::i64 : MVT::i32;
5643 for (
unsigned i = 0, e = RegsToPass.size(); i != e; ++i)
5645 RegsToPass[i].second.getValueType()));
5662 assert(Mask &&
"Missing call preserved mask for calling convention");
5670SDValue PPCTargetLowering::FinishCall(
5685 if (!CFlags.IsIndirect)
5689 dl, CFlags.HasNest, Subtarget);
5699 if (CFlags.IsTailCall) {
5703 cast<RegisterSDNode>(Callee)->getReg() == PPC::CTR) ||
5706 isa<ConstantSDNode>(Callee) ||
5708 "Expecting a global address, external symbol, absolute value, "
5709 "register or an indirect tail call when PC Relative calls are "
5713 "Unexpected call opcode for a tail call.");
5720 std::array<EVT, 2> ReturnTypes = {{MVT::Other, MVT::Glue}};
5721 Chain = DAG.
getNode(CallOpc, dl, ReturnTypes, Ops);
5733 Chain = DAG.
getCALLSEQ_END(Chain, NumBytes, BytesCalleePops, Glue, dl);
5736 return LowerCallResult(Chain, Glue, CFlags.CallConv, CFlags.IsVarArg, Ins, dl,
5747 const GlobalValue *CalleeGV = dyn_cast<GlobalValue>(CalleeFunc);
5756 return isEligibleForTCO(CalleeGV, CalleeCC, CallerCC, CB,
5757 CalleeFunc->
isVarArg(), Outs, Ins, CallerFunc,
5761bool PPCTargetLowering::isEligibleForTCO(
5766 bool isCalleeExternalSymbol)
const {
5771 return IsEligibleForTailCallOptimization_64SVR4(
5772 CalleeGV, CalleeCC, CallerCC, CB, isVarArg, Outs, Ins, CallerFunc,
5773 isCalleeExternalSymbol);
5775 return IsEligibleForTailCallOptimization(CalleeGV, CalleeCC, CallerCC,
5798 auto *
G = dyn_cast<GlobalAddressSDNode>(Callee);
5800 bool IsCalleeExternalSymbol = isa<ExternalSymbolSDNode>(Callee);
5803 isEligibleForTCO(GV, CallConv, CallerCC, CB, isVarArg, Outs, Ins,
5817 isa<GlobalAddressSDNode>(Callee)) &&
5818 "Callee should be an llvm::Function object.");
5821 <<
"\nTCO callee: ");
5828 "site marked musttail");
5833 if (Subtarget.useLongCalls() && isa<GlobalAddressSDNode>(Callee) &&
5835 Callee = LowerGlobalAddress(Callee, DAG);
5838 CallConv, isTailCall, isVarArg, isPatchPoint,
5846 return LowerCall_AIX(Chain, Callee, CFlags, Outs, OutVals, Ins, dl, DAG,
5851 return LowerCall_64SVR4(Chain, Callee, CFlags, Outs, OutVals, Ins, dl, DAG,
5853 return LowerCall_32SVR4(Chain, Callee, CFlags, Outs, OutVals, Ins, dl, DAG,
5857SDValue PPCTargetLowering::LowerCall_32SVR4(
5868 const bool IsVarArg = CFlags.IsVarArg;
5869 const bool IsTailCall = CFlags.IsTailCall;
5875 const Align PtrAlign(4);
5900 CCInfo.PreAnalyzeCallOperands(Outs);
5906 unsigned NumArgs = Outs.
size();
5908 for (
unsigned i = 0; i != NumArgs; ++i) {
5909 MVT ArgVT = Outs[i].VT;
5913 if (Outs[i].IsFixed) {
5923 errs() <<
"Call operand #" << i <<
" has unhandled type "
5933 CCInfo.clearWasPPCF128();
5940 CCByValInfo.AllocateStack(CCInfo.getStackSize(), PtrAlign);
5947 unsigned NumBytes = CCByValInfo.getStackSize();
5961 Chain = EmitTailCallLoadFPAndRetAddr(DAG, SPDiff, Chain, LROp, FPOp, dl);
5972 bool seenFloatArg =
false;
5977 for (
unsigned i = 0, RealArgIdx = 0, j = 0, e = ArgLocs.
size();
5979 ++i, ++RealArgIdx) {
5981 SDValue Arg = OutVals[RealArgIdx];
5984 if (
Flags.isByVal()) {
5989 assert((j < ByValArgLocs.
size()) &&
"Index out of bounds!");
6012 Chain = CallSeqStart = NewCallSeqStart;
6031 if (Subtarget.hasSPE() && Arg.
getValueType() == MVT::f64) {
6038 RegsToPass.
push_back(std::make_pair(ArgLocs[++i].getLocReg(),
6062 if (!MemOpChains.
empty())
6068 for (
unsigned i = 0, e = RegsToPass.
size(); i != e; ++i) {
6069 Chain = DAG.
getCopyToReg(Chain, dl, RegsToPass[i].first,
6070 RegsToPass[i].second, InGlue);
6078 SDValue Ops[] = { Chain, InGlue };
6090 return FinishCall(CFlags, dl, DAG, RegsToPass, InGlue, Chain, CallSeqStart,
6091 Callee, SPDiff, NumBytes, Ins, InVals, CB);
6096SDValue PPCTargetLowering::createMemcpyOutsideCallSeq(
6108 return NewCallSeqStart;
6111SDValue PPCTargetLowering::LowerCall_64SVR4(
6120 unsigned NumOps = Outs.
size();
6121 bool IsSibCall =
false;
6125 unsigned PtrByteSize = 8;
6140 assert(!(IsFastCall && CFlags.IsVarArg) &&
6141 "fastcc not supported on varargs functions");
6148 unsigned NumBytes = LinkageSize;
6149 unsigned GPR_idx = 0, FPR_idx = 0, VR_idx = 0;
6152 PPC::X3, PPC::X4, PPC::X5, PPC::X6,
6153 PPC::X7, PPC::X8, PPC::X9, PPC::X10,
6156 PPC::V2, PPC::V3, PPC::V4, PPC::V5, PPC::V6, PPC::V7, PPC::V8,
6157 PPC::V9, PPC::V10, PPC::V11, PPC::V12, PPC::V13
6160 const unsigned NumGPRs = std::size(GPR);
6162 const unsigned NumVRs = std::size(VR);
6168 bool HasParameterArea = !isELFv2ABI || CFlags.IsVarArg || IsFastCall;
6169 if (!HasParameterArea) {
6170 unsigned ParamAreaSize = NumGPRs * PtrByteSize;
6171 unsigned AvailableFPRs = NumFPRs;
6172 unsigned AvailableVRs = NumVRs;
6173 unsigned NumBytesTmp = NumBytes;
6174 for (
unsigned i = 0; i != NumOps; ++i) {
6175 if (Outs[i].
Flags.isNest())
continue;
6177 PtrByteSize, LinkageSize, ParamAreaSize,
6178 NumBytesTmp, AvailableFPRs, AvailableVRs))
6179 HasParameterArea =
true;
6185 unsigned NumGPRsUsed = 0, NumFPRsUsed = 0, NumVRsUsed = 0;
6190 HasParameterArea =
false;
6193 for (
unsigned i = 0; i != NumOps; ++i) {
6195 EVT ArgVT = Outs[i].VT;
6196 EVT OrigVT = Outs[i].ArgVT;
6202 if (
Flags.isByVal()) {
6203 NumGPRsUsed += (
Flags.getByValSize()+7)/8;
6204 if (NumGPRsUsed > NumGPRs)
6205 HasParameterArea =
true;
6212 if (++NumGPRsUsed <= NumGPRs)
6222 if (++NumVRsUsed <= NumVRs)
6226 if (++NumVRsUsed <= NumVRs)
6231 if (++NumFPRsUsed <= NumFPRs)
6235 HasParameterArea =
true;
6242 NumBytes =
alignTo(NumBytes, Alignement);
6245 if (
Flags.isInConsecutiveRegsLast())
6246 NumBytes = ((NumBytes + PtrByteSize - 1)/PtrByteSize) * PtrByteSize;
6249 unsigned NumBytesActuallyUsed = NumBytes;
6259 if (HasParameterArea)
6260 NumBytes = std::max(NumBytes, LinkageSize + 8 * PtrByteSize);
6262 NumBytes = LinkageSize;
6277 if (CFlags.IsTailCall)
6289 Chain = EmitTailCallLoadFPAndRetAddr(DAG, SPDiff, Chain, LROp, FPOp, dl);
6300 unsigned ArgOffset = LinkageSize;
6306 for (
unsigned i = 0; i != NumOps; ++i) {
6309 EVT ArgVT = Outs[i].VT;
6310 EVT OrigVT = Outs[i].ArgVT;
6319 auto ComputePtrOff = [&]() {
6323 ArgOffset =
alignTo(ArgOffset, Alignment);
6334 GPR_idx = (ArgOffset - LinkageSize) / PtrByteSize;
6335 GPR_idx = std::min(GPR_idx, NumGPRs);
6342 Arg = DAG.
getNode(ExtOp, dl, MVT::i64, Arg);
6348 if (
Flags.isByVal()) {
6366 EVT VT = (
Size==1) ? MVT::i8 : ((
Size==2) ? MVT::i16 : MVT::i32);
6367 if (GPR_idx != NumGPRs) {
6371 RegsToPass.
push_back(std::make_pair(GPR[GPR_idx++], Load));
6373 ArgOffset += PtrByteSize;
6378 if (GPR_idx == NumGPRs &&
Size < 8) {
6380 if (!isLittleEndian) {
6385 Chain = CallSeqStart = createMemcpyOutsideCallSeq(Arg, AddPtr,
6388 ArgOffset += PtrByteSize;
6397 if ((NumGPRs - GPR_idx) * PtrByteSize <
Size)
6398 Chain = CallSeqStart = createMemcpyOutsideCallSeq(Arg, PtrOff,
6403 if (
Size < 8 && GPR_idx != NumGPRs) {
6413 if (!isLittleEndian) {
6417 Chain = CallSeqStart = createMemcpyOutsideCallSeq(Arg, AddPtr,
6425 RegsToPass.
push_back(std::make_pair(GPR[GPR_idx++], Load));
6428 ArgOffset += PtrByteSize;
6434 for (
unsigned j=0;
j<
Size;
j+=PtrByteSize) {
6437 if (GPR_idx != NumGPRs) {
6438 unsigned LoadSizeInBits = std::min(PtrByteSize, (
Size - j)) * 8;
6444 RegsToPass.
push_back(std::make_pair(GPR[GPR_idx++], Load));
6445 ArgOffset += PtrByteSize;
6447 ArgOffset += ((
Size -
j + PtrByteSize-1)/PtrByteSize)*PtrByteSize;
6459 if (
Flags.isNest()) {
6461 RegsToPass.
push_back(std::make_pair(PPC::X11, Arg));
6468 if (GPR_idx != NumGPRs) {
6469 RegsToPass.
push_back(std::make_pair(GPR[GPR_idx++], Arg));
6474 assert(HasParameterArea &&
6475 "Parameter area must exist to pass an argument in memory.");
6477 true, CFlags.IsTailCall,
false, MemOpChains,
6478 TailCallArguments, dl);
6480 ArgOffset += PtrByteSize;
6483 ArgOffset += PtrByteSize;
6496 bool NeedGPROrStack = CFlags.IsVarArg || FPR_idx == NumFPRs;
6497 bool NeededLoad =
false;
6500 if (FPR_idx != NumFPRs)
6501 RegsToPass.
push_back(std::make_pair(
FPR[FPR_idx++], Arg));
6504 if (!NeedGPROrStack)
6506 else if (GPR_idx != NumGPRs && !IsFastCall) {
6520 }
else if (!
Flags.isInConsecutiveRegs()) {
6526 }
else if (ArgOffset % PtrByteSize != 0) {
6530 if (!isLittleEndian)
6535 }
else if (
Flags.isInConsecutiveRegsLast()) {
6538 if (!isLittleEndian)
6548 RegsToPass.
push_back(std::make_pair(GPR[GPR_idx++], ArgVal));
6556 !isLittleEndian && !
Flags.isInConsecutiveRegs()) {
6561 assert(HasParameterArea &&
6562 "Parameter area must exist to pass an argument in memory.");
6564 true, CFlags.IsTailCall,
false, MemOpChains,
6565 TailCallArguments, dl);
6572 if (!IsFastCall || NeededLoad) {
6574 Flags.isInConsecutiveRegs()) ? 4 : 8;
6575 if (
Flags.isInConsecutiveRegsLast())
6576 ArgOffset = ((ArgOffset + PtrByteSize - 1)/PtrByteSize) * PtrByteSize;
6596 if (CFlags.IsVarArg) {
6597 assert(HasParameterArea &&
6598 "Parameter area must exist if we have a varargs call.");
6604 if (VR_idx != NumVRs) {
6608 RegsToPass.
push_back(std::make_pair(VR[VR_idx++], Load));
6611 for (
unsigned i=0; i<16; i+=PtrByteSize) {
6612 if (GPR_idx == NumGPRs)
6619 RegsToPass.
push_back(std::make_pair(GPR[GPR_idx++], Load));
6625 if (VR_idx != NumVRs) {
6626 RegsToPass.
push_back(std::make_pair(VR[VR_idx++], Arg));
6631 assert(HasParameterArea &&
6632 "Parameter area must exist to pass an argument in memory.");
6634 true, CFlags.IsTailCall,
true, MemOpChains,
6635 TailCallArguments, dl);
6646 assert((!HasParameterArea || NumBytesActuallyUsed == ArgOffset) &&
6647 "mismatch in size of parameter area");
6648 (void)NumBytesActuallyUsed;
6650 if (!MemOpChains.
empty())
6656 if (CFlags.IsIndirect) {
6660 assert(!CFlags.IsTailCall &&
"Indirect tails calls not supported");
6675 if (isELFv2ABI && !CFlags.IsPatchPoint)
6676 RegsToPass.
push_back(std::make_pair((
unsigned)PPC::X12, Callee));
6682 for (
unsigned i = 0, e = RegsToPass.
size(); i != e; ++i) {
6683 Chain = DAG.
getCopyToReg(Chain, dl, RegsToPass[i].first,
6684 RegsToPass[i].second, InGlue);
6688 if (CFlags.IsTailCall && !IsSibCall)
6692 return FinishCall(CFlags, dl, DAG, RegsToPass, InGlue, Chain, CallSeqStart,
6693 Callee, SPDiff, NumBytes, Ins, InVals, CB);
6700 "Required alignment greater than stack alignment.");
6720 return RequiredAlign <= 8;
6725 return RequiredAlign <= 4;
6735 const bool IsPPC64 = Subtarget.
isPPC64();
6737 const MVT RegVT = IsPPC64 ? MVT::i64 : MVT::i32;
6739 if (ValVT == MVT::f128)
6746 PPC::R3, PPC::R4, PPC::R5, PPC::R6,
6747 PPC::R7, PPC::R8, PPC::R9, PPC::R10};
6749 PPC::X3, PPC::X4, PPC::X5, PPC::X6,
6750 PPC::X7, PPC::X8, PPC::X9, PPC::X10};
6753 PPC::V2, PPC::V3, PPC::V4, PPC::V5,
6754 PPC::V6, PPC::V7, PPC::V8, PPC::V9,
6755 PPC::V10, PPC::V11, PPC::V12, PPC::V13};
6760 "register width are not supported.");
6766 if (ByValSize == 0) {
6772 const unsigned StackSize =
alignTo(ByValSize, PtrAlign);
6776 if (
unsigned Reg = State.
AllocateReg(IsPPC64 ? GPR_64 : GPR_32))
6794 assert(IsPPC64 &&
"PPC32 should have split i64 values.");
6803 if (
unsigned Reg = State.
AllocateReg(IsPPC64 ? GPR_64 : GPR_32))
6823 for (
unsigned I = 0;
I < StoreSize;
I += PtrAlign.
value()) {
6824 if (
unsigned Reg = State.
AllocateReg(IsPPC64 ? GPR_64 : GPR_32)) {
6825 assert(FReg &&
"An FPR should be available when a GPR is reserved.");
6858 const unsigned VecSize = 16;
6859 const Align VecAlign(VecSize);
6876 const unsigned PtrSize = IsPPC64 ? 8 : 4;
6882 while (NextRegIndex != GPRs.
size() &&
6887 assert(Reg &&
"Allocating register unexpectedly failed.");
6900 for (
unsigned I = 0;
I != VecSize;
I += PtrSize)
6912 if (NextRegIndex == GPRs.
size()) {
6921 if (GPRs[NextRegIndex] == PPC::R9) {
6926 const unsigned FirstReg = State.
AllocateReg(PPC::R9);
6927 const unsigned SecondReg = State.
AllocateReg(PPC::R10);
6928 assert(FirstReg && SecondReg &&
6929 "Allocating R9 or R10 unexpectedly failed.");
6943 for (
unsigned I = 0;
I != VecSize;
I += PtrSize) {
6945 assert(Reg &&
"Failed to allocated register for vararg vector argument");
6960 assert((IsPPC64 || SVT != MVT::i64) &&
6961 "i64 should have been split for 32-bit codegen.");
6969 return IsPPC64 ? &PPC::G8RCRegClass : &PPC::GPRCRegClass;
6971 return HasP8Vector ? &PPC::VSSRCRegClass : &PPC::F4RCRegClass;
6973 return HasVSX ? &PPC::VSFRCRegClass : &PPC::F8RCRegClass;
6981 return &PPC::VRRCRegClass;
6994 else if (Flags.isZExt())
7004 if (PPC::GPRCRegClass.
contains(Reg)) {
7005 assert(Reg >= PPC::R3 && Reg <= PPC::R10 &&
7006 "Reg must be a valid argument register!");
7007 return LASize + 4 * (Reg - PPC::R3);
7010 if (PPC::G8RCRegClass.
contains(Reg)) {
7011 assert(Reg >= PPC::X3 && Reg <= PPC::X10 &&
7012 "Reg must be a valid argument register!");
7013 return LASize + 8 * (Reg - PPC::X3);
7059SDValue PPCTargetLowering::LowerFormalArguments_AIX(
7066 "Unexpected calling convention!");
7076 const bool IsPPC64 = Subtarget.
isPPC64();
7077 const unsigned PtrByteSize = IsPPC64 ? 8 : 4;
7089 CCInfo.AllocateStack(LinkageSize,
Align(PtrByteSize));
7090 CCInfo.AnalyzeFormalArguments(Ins,
CC_AIX);
7108 auto HandleMemLoc = [&]() {
7111 assert((ValSize <= LocSize) &&
7112 "Object size is larger than size of MemLoc");
7115 if (LocSize > ValSize)
7116 CurArgOffset += LocSize - ValSize;
7118 const bool IsImmutable =
7133 assert(isVarArg &&
"Only use custom memloc for vararg.");
7136 const unsigned OriginalValNo = VA.
getValNo();
7137 (void)OriginalValNo;
7139 auto HandleCustomVecRegLoc = [&]() {
7140 assert(
I !=
End && ArgLocs[
I].isRegLoc() && ArgLocs[
I].needsCustom() &&
7141 "Missing custom RegLoc.");
7144 "Unexpected Val type for custom RegLoc.");
7146 "ValNo mismatch between custom MemLoc and RegLoc.");
7150 Subtarget.hasVSX()));
7157 HandleCustomVecRegLoc();
7158 HandleCustomVecRegLoc();
7162 if (
I !=
End && ArgLocs[
I].isRegLoc() && ArgLocs[
I].needsCustom()) {
7164 "Only 2 custom RegLocs expected for 64-bit codegen.");
7165 HandleCustomVecRegLoc();
7166 HandleCustomVecRegLoc();
7210 const unsigned Size =
7222 if (
Flags.isByVal()) {
7228 if (
Flags.getNonZeroByValAlign() > PtrByteSize)
7231 const unsigned StackSize =
alignTo(
Flags.getByValSize(), PtrByteSize);
7240 IsPPC64 ? &PPC::G8RCRegClass : &PPC::GPRCRegClass;
7242 auto HandleRegLoc = [&, RegClass, LocVT](
const MCPhysReg PhysReg,
7255 CopyFrom.
getValue(1), dl, CopyFrom,
7265 for (;
Offset != StackSize && ArgLocs[
I].isRegLoc();
7268 "RegLocs should be for ByVal argument.");
7275 if (
Offset != StackSize) {
7277 "Expected MemLoc for remaining bytes.");
7278 assert(ArgLocs[
I].isMemLoc() &&
"Expected MemLoc for remaining bytes.");
7292 Subtarget.hasVSX()));
7309 const unsigned MinParameterSaveArea = 8 * PtrByteSize;
7311 unsigned CallerReservedArea = std::max<unsigned>(
7312 CCInfo.getStackSize(), LinkageSize + MinParameterSaveArea);
7318 CallerReservedArea =
7327 static const MCPhysReg GPR_32[] = {PPC::R3, PPC::R4, PPC::R5, PPC::R6,
7328 PPC::R7, PPC::R8, PPC::R9, PPC::R10};
7330 static const MCPhysReg GPR_64[] = {PPC::X3, PPC::X4, PPC::X5, PPC::X6,
7331 PPC::X7, PPC::X8, PPC::X9, PPC::X10};
7332 const unsigned NumGPArgRegs = std::size(IsPPC64 ? GPR_64 : GPR_32);
7337 for (
unsigned GPRIndex =
7338 (CCInfo.getStackSize() - LinkageSize) / PtrByteSize;
7339 GPRIndex < NumGPArgRegs; ++GPRIndex) {
7342 IsPPC64 ? MF.
addLiveIn(GPR_64[GPRIndex], &PPC::G8RCRegClass)
7343 : MF.
addLiveIn(GPR_32[GPRIndex], &PPC::GPRCRegClass);
7355 if (!MemOps.
empty())
7361SDValue PPCTargetLowering::LowerCall_AIX(
7374 "Unexpected calling convention!");
7376 if (CFlags.IsPatchPoint)
7383 AIXCCState CCInfo(CFlags.CallConv, CFlags.IsVarArg, MF, ArgLocs,
7391 const bool IsPPC64 = Subtarget.
isPPC64();
7393 const unsigned PtrByteSize = IsPPC64 ? 8 : 4;
7394 CCInfo.AllocateStack(LinkageSize,
Align(PtrByteSize));
7395 CCInfo.AnalyzeCallOperands(Outs,
CC_AIX);
7403 const unsigned MinParameterSaveAreaSize = 8 * PtrByteSize;
7404 const unsigned NumBytes = std::max<unsigned>(
7405 LinkageSize + MinParameterSaveAreaSize, CCInfo.getStackSize());
7421 for (
unsigned I = 0,
E = ArgLocs.
size();
I !=
E;) {
7422 const unsigned ValNo = ArgLocs[
I].getValNo();
7426 if (
Flags.isByVal()) {
7427 const unsigned ByValSize =
Flags.getByValSize();
7435 auto GetLoad = [&](
EVT VT,
unsigned LoadOffset) {
7444 unsigned LoadOffset = 0;
7447 while (LoadOffset + PtrByteSize <= ByValSize && ArgLocs[
I].isRegLoc()) {
7450 LoadOffset += PtrByteSize;
7453 "Unexpected location for pass-by-value argument.");
7457 if (LoadOffset == ByValSize)
7461 assert(ArgLocs[
I].getValNo() == ValNo &&
7462 "Expected additional location for by-value argument.");
7464 if (ArgLocs[
I].isMemLoc()) {
7465 assert(LoadOffset < ByValSize &&
"Unexpected memloc for by-val arg.");
7470 Chain = CallSeqStart = createMemcpyOutsideCallSeq(
7476 CallSeqStart, MemcpyFlags, DAG, dl);
7485 const unsigned ResidueBytes = ByValSize % PtrByteSize;
7486 assert(ResidueBytes != 0 && LoadOffset + PtrByteSize > ByValSize &&
7487 "Unexpected register residue for by-value argument.");
7489 for (
unsigned Bytes = 0; Bytes != ResidueBytes;) {
7493 : ((
N == 2) ? MVT::i16 : (
N == 4 ? MVT::i32 : MVT::i64));
7503 "Unexpected load emitted during handling of pass-by-value "
7511 ResidueVal = ResidueVal ? DAG.
getNode(
ISD::OR, dl, PtrVT, ResidueVal,
7546 assert(CFlags.IsVarArg &&
"Custom MemLocs only used for Vector args.");
7554 const unsigned OriginalValNo = VA.
getValNo();
7556 unsigned LoadOffset = 0;
7557 auto HandleCustomVecRegLoc = [&]() {
7558 assert(
I !=
E &&
"Unexpected end of CCvalAssigns.");
7559 assert(ArgLocs[
I].isRegLoc() && ArgLocs[
I].needsCustom() &&
7560 "Expected custom RegLoc.");
7563 "Custom MemLoc ValNo and custom RegLoc ValNo must match.");
7569 LoadOffset += PtrByteSize;
7575 HandleCustomVecRegLoc();
7576 HandleCustomVecRegLoc();
7578 if (
I !=
E && ArgLocs[
I].isRegLoc() && ArgLocs[
I].needsCustom() &&
7579 ArgLocs[
I].getValNo() == OriginalValNo) {
7581 "Only 2 custom RegLocs expected for 64-bit codegen.");
7582 HandleCustomVecRegLoc();
7583 HandleCustomVecRegLoc();
7601 "Unexpected register handling for calling convention.");
7607 "Custom register handling only expected for VarArg.");
7625 "Unexpected custom register for argument!");
7646 if (!MemOpChains.
empty())
7651 if (CFlags.IsIndirect) {
7652 assert(!CFlags.IsTailCall &&
"Indirect tail-calls not supported.");
7655 const MVT PtrVT = Subtarget.
isPPC64() ? MVT::i64 : MVT::i32;
7656 const unsigned TOCSaveOffset =
7672 for (
auto Reg : RegsToPass) {
7677 const int SPDiff = 0;
7678 return FinishCall(CFlags, dl, DAG, RegsToPass, InGlue, Chain, CallSeqStart,
7679 Callee, SPDiff, NumBytes, Ins, InVals, CB);
7688 CCState CCInfo(CallConv, isVarArg, MF, RVLocs, Context);
7689 return CCInfo.CheckReturn(
7704 CCInfo.AnalyzeReturn(Outs,
7713 for (
unsigned i = 0, RealResIdx = 0; i != RVLocs.
size(); ++i, ++RealResIdx) {
7717 SDValue Arg = OutVals[RealResIdx];
7732 if (Subtarget.hasSPE() && VA.
getLocVT() == MVT::f64) {
7755 RetOps.push_back(Glue);
7761PPCTargetLowering::LowerGET_DYNAMIC_AREA_OFFSET(
SDValue Op,
7766 EVT IntVT =
Op.getValueType();
7770 SDValue FPSIdx = getFramePointerFrameIndex(DAG);
7772 SDValue Ops[2] = {Chain, FPSIdx};
7786 bool isPPC64 = Subtarget.
isPPC64();
7787 unsigned SP = isPPC64 ? PPC::X1 : PPC::R1;
7807 bool isPPC64 = Subtarget.
isPPC64();
7828PPCTargetLowering::getFramePointerFrameIndex(
SelectionDAG & DAG)
const {
7830 bool isPPC64 = Subtarget.
isPPC64();
7864 SDValue FPSIdx = getFramePointerFrameIndex(DAG);
7865 SDValue Ops[3] = { Chain, NegSize, FPSIdx };
7876 bool isPPC64 = Subtarget.
isPPC64();
7888 Op.getOperand(0),
Op.getOperand(1));
7895 Op.getOperand(0),
Op.getOperand(1));
7899 if (
Op.getValueType().isVector())
7900 return LowerVectorLoad(
Op, DAG);
7902 assert(
Op.getValueType() == MVT::i1 &&
7903 "Custom lowering only for i1 loads");
7916 BasePtr, MVT::i8, MMO);
7924 if (
Op.getOperand(1).getValueType().isVector())
7925 return LowerVectorStore(
Op, DAG);
7927 assert(
Op.getOperand(1).getValueType() == MVT::i1 &&
7928 "Custom lowering only for i1 stores");
7947 assert(
Op.getValueType() == MVT::i1 &&
7948 "Custom lowering only for i1 results");
7976 EVT TrgVT =
Op.getValueType();
7989 !llvm::has_single_bit<uint32_t>(
8000 if (SrcSize == 256) {
8011 Op1 = SrcSize == 128 ? N1 :
widenVec(DAG, N1,
DL);
8019 for (
unsigned i = 0; i < TrgNumElts; ++i)
8022 for (
unsigned i = 1; i <= TrgNumElts; ++i)
8026 for (
unsigned i = TrgNumElts; i < WideNumElts; ++i)
8039 EVT ResVT =
Op.getValueType();
8040 EVT CmpVT =
Op.getOperand(0).getValueType();
8042 SDValue TV =
Op.getOperand(2), FV =
Op.getOperand(3);
8048 if (!Subtarget.hasP9Vector() && CmpVT == MVT::f128) {
8065 if (Subtarget.hasP9Vector() && LHS == TV && RHS == FV) {
8097 if (
LHS.getValueType() == MVT::f32)
8110 if (
LHS.getValueType() == MVT::f32)
8119 if (
LHS.getValueType() == MVT::f32)
8133 if (
Cmp.getValueType() == MVT::f32)
8143 if (
Cmp.getValueType() == MVT::f32)
8149 if (
Cmp.getValueType() == MVT::f32)
8155 if (
Cmp.getValueType() == MVT::f32)
8161 if (
Cmp.getValueType() == MVT::f32)
8194 bool IsStrict =
Op->isStrictFPOpcode();
8200 Flags.setNoFPExcept(
Op->getFlags().hasNoFPExcept());
8203 SDValue Src =
Op.getOperand(IsStrict ? 1 : 0);
8205 MVT DestTy =
Op.getSimpleValueType();
8206 assert(Src.getValueType().isFloatingPoint() &&
8207 (DestTy == MVT::i8 || DestTy == MVT::i16 || DestTy == MVT::i32 ||
8208 DestTy == MVT::i64) &&
8209 "Invalid FP_TO_INT types");
8210 if (Src.getValueType() == MVT::f32) {
8214 DAG.
getVTList(MVT::f64, MVT::Other), {Chain, Src}, Flags);
8215 Chain = Src.getValue(1);
8219 if ((DestTy == MVT::i8 || DestTy == MVT::i16) && Subtarget.hasP9Vector())
8220 DestTy = Subtarget.
isPPC64() ? MVT::i64 : MVT::i32;
8229 assert((IsSigned || Subtarget.hasFPCVT()) &&
8230 "i64 FP_TO_UINT is supported only with FPCVT");
8233 EVT ConvTy = Src.getValueType() == MVT::f128 ? MVT::f128 : MVT::f64;
8237 Conv = DAG.
getNode(Opc, dl, DAG.
getVTList(ConvTy, MVT::Other), {Chain, Src},
8240 Conv = DAG.
getNode(Opc, dl, ConvTy, Src);
8245void PPCTargetLowering::LowerFP_TO_INTForReuse(
SDValue Op, ReuseLoadInfo &RLI,
8247 const SDLoc &dl)
const {
8251 bool IsStrict =
Op->isStrictFPOpcode();
8254 bool i32Stack =
Op.getValueType() == MVT::i32 && Subtarget.hasSTFIWX() &&
8255 (IsSigned || Subtarget.hasFPCVT());
8257 int FI = cast<FrameIndexSDNode>(FIPtr)->getIndex();
8266 Alignment =
Align(4);
8269 SDValue Ops[] = { Chain, Tmp, FIPtr };
8271 DAG.
getVTList(MVT::Other), Ops, MVT::i32, MMO);
8273 Chain = DAG.
getStore(Chain, dl, Tmp, FIPtr, MPI, Alignment);
8277 if (
Op.getValueType() == MVT::i32 && !i32Stack) {
8286 RLI.Alignment = Alignment;
8294 const SDLoc &dl)
const {
8297 if (
Op->isStrictFPOpcode())
8304 const SDLoc &dl)
const {
8305 bool IsStrict =
Op->isStrictFPOpcode();
8308 SDValue Src =
Op.getOperand(IsStrict ? 1 : 0);
8309 EVT SrcVT = Src.getValueType();
8310 EVT DstVT =
Op.getValueType();
8313 if (SrcVT == MVT::f128)
8314 return Subtarget.hasP9Vector() ?
Op :
SDValue();
8318 if (SrcVT == MVT::ppcf128) {
8319 if (DstVT == MVT::i32) {
8324 Flags.setNoFPExcept(
Op->getFlags().hasNoFPExcept());
8335 {Op.getOperand(0), Lo, Hi}, Flags);
8338 {Res.getValue(1), Res}, Flags);
8344 const uint64_t TwoE31[] = {0x41e0000000000000LL, 0};
8368 {Chain, Src, FltOfs}, Flags);
8372 {Chain, Val}, Flags);
8375 dl, DstVT, Sel, DAG.
getConstant(0, dl, DstVT), SignMask);
8393 if (Subtarget.hasDirectMove() && Subtarget.
isPPC64())
8394 return LowerFP_TO_INTDirectMove(
Op, DAG, dl);
8397 LowerFP_TO_INTForReuse(
Op, RLI, DAG, dl);
8399 return DAG.
getLoad(
Op.getValueType(), dl, RLI.Chain, RLI.Ptr, RLI.MPI,
8400 RLI.Alignment, RLI.MMOFlags(), RLI.AAInfo, RLI.Ranges);
8411bool PPCTargetLowering::canReuseLoadAddress(
SDValue Op,
EVT MemVT,
8416 if (
Op->isStrictFPOpcode())
8421 (Subtarget.hasFPCVT() ||
Op.getValueType() == MVT::i32);
8425 Op.getOperand(0).getValueType())) {
8427 LowerFP_TO_INTForReuse(
Op, RLI, DAG, dl);
8432 if (!LD ||
LD->getExtensionType() != ET ||
LD->isVolatile() ||
8433 LD->isNonTemporal())
8435 if (
LD->getMemoryVT() != MemVT)
8445 RLI.Ptr =
LD->getBasePtr();
8446 if (
LD->isIndexed() && !
LD->getOffset().isUndef()) {
8448 "Non-pre-inc AM on PPC?");
8453 RLI.Chain =
LD->getChain();
8454 RLI.MPI =
LD->getPointerInfo();
8455 RLI.IsDereferenceable =
LD->isDereferenceable();
8456 RLI.IsInvariant =
LD->isInvariant();
8457 RLI.Alignment =
LD->getAlign();
8458 RLI.AAInfo =
LD->getAAInfo();
8459 RLI.Ranges =
LD->getRanges();
8461 RLI.ResChain =
SDValue(LD,
LD->isIndexed() ? 2 : 1);
8469void PPCTargetLowering::spliceIntoChain(
SDValue ResChain,
8475 SDLoc dl(NewResChain);
8478 NewResChain, DAG.
getUNDEF(MVT::Other));
8480 "A new TF really is required here");
8489bool PPCTargetLowering::directMoveIsProfitable(
const SDValue &
Op)
const {
8490 SDNode *Origin =
Op.getOperand(
Op->isStrictFPOpcode() ? 1 : 0).getNode();
8497 if (!Subtarget.hasP9Vector() && MMO->
getSize() <= 2)
8505 if (UI.getUse().get().getResNo() != 0)
8527 Flags.setNoFPExcept(
Op->getFlags().hasNoFPExcept());
8531 bool IsSingle =
Op.getValueType() == MVT::f32 && Subtarget.hasFPCVT();
8534 EVT ConvTy = IsSingle ? MVT::f32 : MVT::f64;
8535 if (
Op->isStrictFPOpcode()) {
8537 Chain =
Op.getOperand(0);
8539 DAG.
getVTList(ConvTy, MVT::Other), {Chain, Src}, Flags);
8541 return DAG.
getNode(ConvOpc, dl, ConvTy, Src);
8549 const SDLoc &dl)
const {
8550 assert((
Op.getValueType() == MVT::f32 ||
8551 Op.getValueType() == MVT::f64) &&
8552 "Invalid floating point type as target of conversion");
8553 assert(Subtarget.hasFPCVT() &&
8554 "Int to FP conversions with direct moves require FPCVT");
8555 SDValue Src =
Op.getOperand(
Op->isStrictFPOpcode() ? 1 : 0);
8556 bool WordInt = Src.getSimpleValueType().SimpleTy == MVT::i32;
8578 for (
unsigned i = 1; i < NumConcat; ++i)
8585 const SDLoc &dl)
const {
8586 bool IsStrict =
Op->isStrictFPOpcode();
8587 unsigned Opc =
Op.getOpcode();
8588 SDValue Src =
Op.getOperand(IsStrict ? 1 : 0);
8591 "Unexpected conversion type");
8592 assert((
Op.getValueType() == MVT::v2f64 ||
Op.getValueType() == MVT::v4f32) &&
8593 "Supports conversions to v2f64/v4f32 only.");
8597 Flags.setNoFPExcept(
Op->getFlags().hasNoFPExcept());
8600 bool FourEltRes =
Op.getValueType() == MVT::v4f32;
8605 MVT IntermediateVT = FourEltRes ? MVT::v4i32 : MVT::v2i64;
8608 for (
unsigned i = 0; i < WideNumElts; ++i)
8611 int Stride = FourEltRes ? WideNumElts / 4 : WideNumElts / 2;
8612 int SaveElts = FourEltRes ? 4 : 2;
8614 for (
int i = 0; i < SaveElts; i++)
8615 ShuffV[i * Stride] = i;
8617 for (
int i = 1; i <= SaveElts; i++)
8618 ShuffV[i * Stride - 1] = i - 1;
8626 Arrange = DAG.
getBitcast(IntermediateVT, Arrange);
8627 EVT ExtVT = Src.getValueType();
8628 if (Subtarget.hasP9Altivec())
8639 {Op.getOperand(0), Extend}, Flags);
8641 return DAG.
getNode(Opc, dl,
Op.getValueType(), Extend);
8649 bool IsStrict =
Op->isStrictFPOpcode();
8650 SDValue Src =
Op.getOperand(IsStrict ? 1 : 0);
8655 Flags.setNoFPExcept(
Op->getFlags().hasNoFPExcept());
8657 EVT InVT = Src.getValueType();
8658 EVT OutVT =
Op.getValueType();
8661 return LowerINT_TO_FPVector(
Op, DAG, dl);
8664 if (
Op.getValueType() == MVT::f128)
8665 return Subtarget.hasP9Vector() ?
Op :
SDValue();
8668 if (
Op.getValueType() != MVT::f32 &&
Op.getValueType() != MVT::f64)
8671 if (Src.getValueType() == MVT::i1) {
8683 if (Subtarget.hasDirectMove() && directMoveIsProfitable(
Op) &&
8684 Subtarget.
isPPC64() && Subtarget.hasFPCVT())
8685 return LowerINT_TO_FPDirectMove(
Op, DAG, dl);
8687 assert((IsSigned || Subtarget.hasFPCVT()) &&
8688 "UINT_TO_FP is supported only with FPCVT");
8690 if (Src.getValueType() == MVT::i64) {
8702 if (
Op.getValueType() == MVT::f32 &&
8703 !Subtarget.hasFPCVT() &&
8744 if (canReuseLoadAddress(SINT, MVT::i64, RLI, DAG)) {
8745 Bits = DAG.
getLoad(MVT::f64, dl, RLI.Chain, RLI.Ptr, RLI.MPI,
8746 RLI.Alignment, RLI.MMOFlags(), RLI.AAInfo, RLI.Ranges);
8747 spliceIntoChain(RLI.ResChain,
Bits.getValue(1), DAG);
8748 }
else if (Subtarget.hasLFIWAX() &&
8749 canReuseLoadAddress(SINT, MVT::i32, RLI, DAG,
ISD::SEXTLOAD)) {
8752 RLI.Alignment, RLI.AAInfo, RLI.Ranges);
8753 SDValue Ops[] = { RLI.Chain, RLI.Ptr };
8756 Ops, MVT::i32, MMO);
8757 spliceIntoChain(RLI.ResChain,
Bits.getValue(1), DAG);
8758 }
else if (Subtarget.hasFPCVT() &&
8759 canReuseLoadAddress(SINT, MVT::i32, RLI, DAG,
ISD::ZEXTLOAD)) {
8762 RLI.Alignment, RLI.AAInfo, RLI.Ranges);
8763 SDValue Ops[] = { RLI.Chain, RLI.Ptr };
8766 Ops, MVT::i32, MMO);
8767 spliceIntoChain(RLI.ResChain,
Bits.getValue(1), DAG);
8768 }
else if (((Subtarget.hasLFIWAX() &&
8770 (Subtarget.hasFPCVT() &&
8784 assert(cast<StoreSDNode>(Store)->getMemoryVT() == MVT::i32 &&
8785 "Expected an i32 store");
8791 RLI.Alignment =
Align(4);
8795 RLI.Alignment, RLI.AAInfo, RLI.Ranges);
8796 SDValue Ops[] = { RLI.Chain, RLI.Ptr };
8799 dl, DAG.
getVTList(MVT::f64, MVT::Other),
8800 Ops, MVT::i32, MMO);
8801 Chain =
Bits.getValue(1);
8807 Chain =
FP.getValue(1);
8809 if (
Op.getValueType() == MVT::f32 && !Subtarget.hasFPCVT()) {
8813 {Chain, FP, DAG.getIntPtrConstant(0, dl)}, Flags);
8821 assert(Src.getValueType() == MVT::i32 &&
8822 "Unhandled INT_TO_FP type in custom expander!");
8832 if (Subtarget.hasLFIWAX() || Subtarget.hasFPCVT()) {
8835 if (!(ReusingLoad = canReuseLoadAddress(Src, MVT::i32, RLI, DAG))) {
8844 assert(cast<StoreSDNode>(Store)->getMemoryVT() == MVT::i32 &&
8845 "Expected an i32 store");
8851 RLI.Alignment =
Align(4);
8856 RLI.Alignment, RLI.AAInfo, RLI.Ranges);
8857 SDValue Ops[] = { RLI.Chain, RLI.Ptr };
8859 DAG.
getVTList(MVT::f64, MVT::Other), Ops,
8863 spliceIntoChain(RLI.ResChain, Ld.
getValue(1), DAG);
8866 "i32->FP without LFIWAX supported only on PPC64");
8875 Chain, dl, Ext64, FIdx,
8881 MVT::f64, dl, Chain, FIdx,
8889 Chain =
FP.getValue(1);
8890 if (
Op.getValueType() == MVT::f32 && !Subtarget.hasFPCVT()) {
8894 {Chain, FP, DAG.getIntPtrConstant(0, dl)}, Flags);
8925 EVT VT =
Op.getValueType();
8931 Chain =
MFFS.getValue(1);
8945 "Stack slot adjustment is valid only on big endian subtargets!");
8975 EVT VT =
Op.getValueType();
8979 VT ==
Op.getOperand(1).getValueType() &&
8999 SDValue OutOps[] = { OutLo, OutHi };
9004 EVT VT =
Op.getValueType();
9008 VT ==
Op.getOperand(1).getValueType() &&
9028 SDValue OutOps[] = { OutLo, OutHi };
9034 EVT VT =
Op.getValueType();
9037 VT ==
Op.getOperand(1).getValueType() &&
9057 SDValue OutOps[] = { OutLo, OutHi };
9064 EVT VT =
Op.getValueType();
9071 EVT AmtVT =
Z.getValueType();
9094 static const MVT VTys[] = {
9095 MVT::v16i8, MVT::v8i16, MVT::Other, MVT::v4i32
9098 EVT ReqVT = VT != MVT::Other ? VT : VTys[SplatSize-1];
9101 if (Val == ((1LLU << (SplatSize * 8)) - 1)) {
9106 EVT CanonicalVT = VTys[SplatSize-1];
9115 const SDLoc &dl,
EVT DestVT = MVT::Other) {
9116 if (DestVT == MVT::Other) DestVT =
Op.getValueType();
9125 EVT DestVT = MVT::Other) {
9126 if (DestVT == MVT::Other) DestVT =
LHS.getValueType();
9135 EVT DestVT = MVT::Other) {
9138 DAG.
getConstant(IID, dl, MVT::i32), Op0, Op1, Op2);
9150 for (
unsigned i = 0; i != 16; ++i)
9171 EVT VecVT = V->getValueType(0);
9172 bool RightType = VecVT == MVT::v2f64 ||
9173 (HasP8Vector && VecVT == MVT::v4f32) ||
9174 (HasDirectMove && (VecVT == MVT::v2i64 || VecVT == MVT::v4i32));
9178 bool IsSplat =
true;
9179 bool IsLoad =
false;
9180 SDValue Op0 = V->getOperand(0);
9185 if (V->isConstant())
9187 for (
int i = 0, e = V->getNumOperands(); i < e; ++i) {
9188 if (V->getOperand(i).isUndef())
9192 if (V->getOperand(i).getOpcode() ==
ISD::LOAD ||
9194 V->getOperand(i).getOperand(0).getOpcode() ==
ISD::LOAD) ||
9196 V->getOperand(i).getOperand(0).getOpcode() ==
ISD::LOAD) ||
9198 V->getOperand(i).getOperand(0).getOpcode() ==
ISD::LOAD))
9202 if (V->getOperand(i) != Op0 ||
9203 (!IsLoad && !V->isOnlyUserOf(V->getOperand(i).getNode())))
9206 return !(IsSplat && IsLoad);
9215 if ((
Op.getValueType() != MVT::f128) ||
9236 LoadSDNode *LD = cast<LoadSDNode>(*InputLoad);
9244 APFloat APFloatToConvert = ArgAPFloat;
9245 bool LosesInfo =
true;
9250 ArgAPFloat = APFloatToConvert;
9272 APFloat APFloatToConvert = ArgAPFloat;
9273 bool LosesInfo =
true;
9277 return (!LosesInfo && !APFloatToConvert.
isDenormal());
9282 LoadSDNode *InputNode = dyn_cast<LoadSDNode>(
Op.getOperand(0));
9286 EVT Ty =
Op->getValueType(0);
9289 if ((Ty == MVT::v2f64 || Ty == MVT::v4f32 || Ty == MVT::v4i32) &&
9298 if ((Ty == MVT::v8i16 || Ty == MVT::v16i8) &&
ISD::isEXTLoad(InputNode) &&
9302 if (Ty == MVT::v2i64) {
9305 if (MemVT == MVT::i32) {
9325 assert(BVN &&
"Expected a BuildVectorSDNode in LowerBUILD_VECTOR");
9328 APInt APSplatBits, APSplatUndef;
9329 unsigned SplatBitSize;
9331 bool BVNIsConstantSplat =
9339 if (BVNIsConstantSplat && (SplatBitSize == 64) &&
9340 Subtarget.hasPrefixInstrs()) {
9343 if ((
Op->getValueType(0) == MVT::v2f64) &&
9378 if (!BVNIsConstantSplat || SplatBitSize > 32) {
9385 const SDValue *InputLoad = &
Op.getOperand(0);
9390 unsigned MemorySize =
LD->getMemoryVT().getScalarSizeInBits();
9391 unsigned ElementSize =
9394 assert(((ElementSize == 2 * MemorySize)
9398 "Unmatched element size and opcode!\n");
9403 unsigned NumUsesOfInputLD = 128 / ElementSize;
9405 if (BVInOp.isUndef())
9420 if (NumUsesOfInputLD == 1 &&
9423 Subtarget.hasLFIWAX()))
9432 Subtarget.isISA3_1() && ElementSize <= 16)
9435 assert(NumUsesOfInputLD > 0 &&
"No uses of input LD of a build_vector?");
9437 Subtarget.hasVSX()) {
9444 NewOpcode, dl, DAG.
getVTList(
Op.getValueType(), MVT::Other), Ops,
9445 LD->getMemoryVT(),
LD->getMemOperand());
9457 if (Subtarget.hasVSX() && Subtarget.
isPPC64() &&
9459 Subtarget.hasP8Vector()))
9466 unsigned SplatSize = SplatBitSize / 8;
9471 if (SplatBits == 0) {
9473 if (
Op.getValueType() != MVT::v4i32 || HasAnyUndefs) {
9485 if (Subtarget.hasPrefixInstrs() && SplatSize == 2)
9487 Op.getValueType(), DAG, dl);
9489 if (Subtarget.hasPrefixInstrs() && SplatSize == 4)
9494 if (Subtarget.hasP9Vector() && SplatSize == 1)
9499 int32_t SextVal= (int32_t(SplatBits << (32-SplatBitSize)) >>
9501 if (SextVal >= -16 && SextVal <= 15)
9514 if (SextVal >= -32 && SextVal <= 31) {
9519 EVT VT = (SplatSize == 1 ? MVT::v16i8 :
9520 (SplatSize == 2 ? MVT::v8i16 : MVT::v4i32));
9523 if (VT ==
Op.getValueType())
9532 if (SplatSize == 4 && SplatBits == (0x7FFFFFFF&~SplatUndef)) {
9546 static const signed char SplatCsts[] = {
9547 -1, 1, -2, 2, -3, 3, -4, 4, -5, 5, -6, 6, -7, 7,
9548 -8, 8, -9, 9, -10, 10, -11, 11, -12, 12, -13, 13, 14, -14, 15, -15, -16
9551 for (
unsigned idx = 0; idx < std::size(SplatCsts); ++idx) {
9554 int i = SplatCsts[idx];
9558 unsigned TypeShiftAmt = i & (SplatBitSize-1);
9561 if (SextVal == (
int)((
unsigned)i << TypeShiftAmt)) {
9563 static const unsigned IIDs[] = {
9564 Intrinsic::ppc_altivec_vslb, Intrinsic::ppc_altivec_vslh, 0,
9565 Intrinsic::ppc_altivec_vslw
9572 if (SextVal == (
int)((
unsigned)i >> TypeShiftAmt)) {
9574 static const unsigned IIDs[] = {
9575 Intrinsic::ppc_altivec_vsrb, Intrinsic::ppc_altivec_vsrh, 0,
9576 Intrinsic::ppc_altivec_vsrw
9583 if (SextVal == (
int)(((
unsigned)i << TypeShiftAmt) |
9584 ((
unsigned)i >> (SplatBitSize-TypeShiftAmt)))) {
9586 static const unsigned IIDs[] = {
9587 Intrinsic::ppc_altivec_vrlb, Intrinsic::ppc_altivec_vrlh, 0,
9588 Intrinsic::ppc_altivec_vrlw
9595 if (SextVal == (
int)(((
unsigned)i << 8) | (i < 0 ? 0xFF : 0))) {
9601 if (SextVal == (
int)(((
unsigned)i << 16) | (i < 0 ? 0xFFFF : 0))) {
9607 if (SextVal == (
int)(((
unsigned)i << 24) | (i < 0 ? 0xFFFFFF : 0))) {
9622 unsigned OpNum = (PFEntry >> 26) & 0x0F;
9623 unsigned LHSID = (PFEntry >> 13) & ((1 << 13)-1);
9624 unsigned RHSID = (PFEntry >> 0) & ((1 << 13)-1);
9640 if (LHSID == (1*9+2)*9+3)
return LHS;
9641 assert(LHSID == ((4*9+5)*9+6)*9+7 &&
"Illegal OP_COPY!");
9653 ShufIdxs[ 0] = 0; ShufIdxs[ 1] = 1; ShufIdxs[ 2] = 2; ShufIdxs[ 3] = 3;
9654 ShufIdxs[ 4] = 16; ShufIdxs[ 5] = 17; ShufIdxs[ 6] = 18; ShufIdxs[ 7] = 19;
9655 ShufIdxs[ 8] = 4; ShufIdxs[ 9] = 5; ShufIdxs[10] = 6; ShufIdxs[11] = 7;
9656 ShufIdxs[12] = 20; ShufIdxs[13] = 21; ShufIdxs[14] = 22; ShufIdxs[15] = 23;
9659 ShufIdxs[ 0] = 8; ShufIdxs[ 1] = 9; ShufIdxs[ 2] = 10; ShufIdxs[ 3] = 11;
9660 ShufIdxs[ 4] = 24; ShufIdxs[ 5] = 25; ShufIdxs[ 6] = 26; ShufIdxs[ 7] = 27;
9661 ShufIdxs[ 8] = 12; ShufIdxs[ 9] = 13; ShufIdxs[10] = 14; ShufIdxs[11] = 15;
9662 ShufIdxs[12] = 28; ShufIdxs[13] = 29; ShufIdxs[14] = 30; ShufIdxs[15] = 31;
9665 for (
unsigned i = 0; i != 16; ++i)
9666 ShufIdxs[i] = (i&3)+0;
9669 for (
unsigned i = 0; i != 16; ++i)
9670 ShufIdxs[i] = (i&3)+4;
9673 for (
unsigned i = 0; i != 16; ++i)
9674 ShufIdxs[i] = (i&3)+8;
9677 for (
unsigned i = 0; i != 16; ++i)
9678 ShufIdxs[i] = (i&3)+12;
9699 const unsigned BytesInVector = 16;
9704 unsigned ShiftElts = 0, InsertAtByte = 0;
9708 unsigned LittleEndianShifts[] = {8, 7, 6, 5, 4, 3, 2, 1,
9709 0, 15, 14, 13, 12, 11, 10, 9};
9710 unsigned BigEndianShifts[] = {9, 10, 11, 12, 13, 14, 15, 0,
9711 1, 2, 3, 4, 5, 6, 7, 8};
9714 int OriginalOrder[] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15};
9726 bool FoundCandidate =
false;
9730 unsigned VINSERTBSrcElem = IsLE ? 8 : 7;
9733 for (
unsigned i = 0; i < BytesInVector; ++i) {
9734 unsigned CurrentElement =
Mask[i];
9737 if (
V2.isUndef() && CurrentElement != VINSERTBSrcElem)
9740 bool OtherElementsInOrder =
true;
9743 for (
unsigned j = 0;
j < BytesInVector; ++
j) {
9750 (!
V2.isUndef() && CurrentElement < BytesInVector) ? BytesInVector : 0;
9751 if (Mask[j] != OriginalOrder[j] + MaskOffset) {
9752 OtherElementsInOrder =
false;
9759 if (OtherElementsInOrder) {
9766 ShiftElts = IsLE ? LittleEndianShifts[CurrentElement & 0xF]
9767 : BigEndianShifts[CurrentElement & 0xF];
9768 Swap = CurrentElement < BytesInVector;
9770 InsertAtByte = IsLE ? BytesInVector - (i + 1) : i;
9771 FoundCandidate =
true;
9776 if (!FoundCandidate)
9800 const unsigned NumHalfWords = 8;
9801 const unsigned BytesInVector = NumHalfWords * 2;
9810 unsigned ShiftElts = 0, InsertAtByte = 0;
9814 unsigned LittleEndianShifts[] = {4, 3, 2, 1, 0, 7, 6, 5};
9815 unsigned BigEndianShifts[] = {5, 6, 7, 0, 1, 2, 3, 4};
9818 uint32_t OriginalOrderLow = 0x1234567;
9819 uint32_t OriginalOrderHigh = 0x89ABCDEF;
9822 for (
unsigned i = 0; i < NumHalfWords; ++i) {
9823 unsigned MaskShift = (NumHalfWords - 1 - i) * 4;
9824 Mask |= ((
uint32_t)(
N->getMaskElt(i * 2) / 2) << MaskShift);
9840 bool FoundCandidate =
false;
9843 for (
unsigned i = 0; i < NumHalfWords; ++i) {
9844 unsigned MaskShift = (NumHalfWords - 1 - i) * 4;
9846 uint32_t MaskOtherElts = ~(0xF << MaskShift);
9854 unsigned VINSERTHSrcElem = IsLE ? 4 : 3;
9855 TargetOrder = OriginalOrderLow;
9859 if (MaskOneElt == VINSERTHSrcElem &&
9860 (Mask & MaskOtherElts) == (TargetOrder & MaskOtherElts)) {
9861 InsertAtByte = IsLE ? BytesInVector - (i + 1) * 2 : i * 2;
9862 FoundCandidate =
true;
9868 (MaskOneElt < NumHalfWords) ? OriginalOrderHigh : OriginalOrderLow;
9870 if ((Mask & MaskOtherElts) == (TargetOrder & MaskOtherElts)) {
9872 ShiftElts = IsLE ? LittleEndianShifts[MaskOneElt & 0x7]
9873 : BigEndianShifts[MaskOneElt & 0x7];
9874 InsertAtByte = IsLE ? BytesInVector - (i + 1) * 2 : i * 2;
9875 Swap = MaskOneElt < NumHalfWords;
9876 FoundCandidate =
true;
9882 if (!FoundCandidate)
9917 auto ShuffleMask = SVN->
getMask();
9932 ShuffleMask = CommutedSV->
getMask();
9941 APInt APSplatValue, APSplatUndef;
9942 unsigned SplatBitSize;
9958 if ((ShuffleMask[0] == 0 && ShuffleMask[8] == 8) &&
9959 (ShuffleMask[4] % 4 == 0 && ShuffleMask[12] % 4 == 0 &&
9960 ShuffleMask[4] > 15 && ShuffleMask[12] > 15))
9962 else if ((ShuffleMask[4] == 4 && ShuffleMask[12] == 12) &&
9963 (ShuffleMask[0] % 4 == 0 && ShuffleMask[8] % 4 == 0 &&
9964 ShuffleMask[0] > 15 && ShuffleMask[8] > 15))
9972 for (; SplatBitSize < 32; SplatBitSize <<= 1)
9973 SplatVal |= (SplatVal << SplatBitSize);
9987 assert(
Op.getValueType() == MVT::v1i128 &&
9988 "Only set v1i128 as custom, other type shouldn't reach here!");
9993 if (SHLAmt % 8 == 0) {
9994 std::array<int, 16>
Mask;
9995 std::iota(
Mask.begin(),
Mask.end(), 0);
9996 std::rotate(
Mask.begin(),
Mask.begin() + SHLAmt / 8,
Mask.end());
10025 if (
SDValue NewShuffle = combineVectorShuffle(SVOp, DAG)) {
10026 if (!isa<ShuffleVectorSDNode>(NewShuffle))
10029 SVOp = cast<ShuffleVectorSDNode>(
Op);
10030 V1 =
Op.getOperand(0);
10031 V2 =
Op.getOperand(1);
10033 EVT VT =
Op.getValueType();
10036 unsigned ShiftElts, InsertAtByte;
10042 bool IsPermutedLoad =
false;
10044 if (InputLoad && Subtarget.hasVSX() &&
V2.isUndef() &&
10054 if (IsPermutedLoad) {
10055 assert((isLittleEndian || IsFourByte) &&
10056 "Unexpected size for permuted load on big endian target");
10057 SplatIdx += IsFourByte ? 2 : 1;
10058 assert((SplatIdx < (IsFourByte ? 4 : 2)) &&
10059 "Splat of a value outside of the loaded memory");
10064 if ((IsFourByte && Subtarget.hasP9Vector()) || !IsFourByte) {
10067 Offset = isLittleEndian ? (3 - SplatIdx) * 4 : SplatIdx * 4;
10069 Offset = isLittleEndian ? (1 - SplatIdx) * 8 : SplatIdx * 8;
10073 if (
LD->getValueType(0).getSizeInBits() == (IsFourByte ? 32 : 64))
10086 DAG.
getVTList(IsFourByte ? MVT::v4i32 : MVT::v2i64, MVT::Other);
10089 Ops,
LD->getMemoryVT(),
LD->getMemOperand());
10098 if (VT == MVT::v2i64 || VT == MVT::v2f64)
10101 if (Subtarget.hasP9Vector() &&
10120 if (Subtarget.hasPrefixInstrs()) {
10122 if ((SplatInsertNode = lowerToXXSPLTI32DX(SVOp, DAG)))
10123 return SplatInsertNode;
10126 if (Subtarget.hasP9Altivec()) {
10128 if ((NewISDNode = lowerToVINSERTH(SVOp, DAG)))
10131 if ((NewISDNode = lowerToVINSERTB(SVOp, DAG)))
10135 if (Subtarget.hasVSX() &&
10148 if (Subtarget.hasVSX() &&
10161 if (Subtarget.hasP9Vector()) {
10181 if (Subtarget.hasVSX()) {
10202 if (
V2.isUndef()) {
10215 (Subtarget.hasP8Altivec() && (
10226 unsigned int ShuffleKind = isLittleEndian ? 2 : 0;
10236 (Subtarget.hasP8Altivec() && (
10247 unsigned PFIndexes[4];
10248 bool isFourElementShuffle =
true;
10249 for (
unsigned i = 0; i != 4 && isFourElementShuffle;
10251 unsigned EltNo = 8;
10252 for (
unsigned j = 0;
j != 4; ++
j) {
10253 if (PermMask[i * 4 + j] < 0)
10256 unsigned ByteSource = PermMask[i * 4 +
j];
10257 if ((ByteSource & 3) != j) {
10258 isFourElementShuffle =
false;
10263 EltNo = ByteSource / 4;
10264 }
else if (EltNo != ByteSource / 4) {
10265 isFourElementShuffle =
false;
10269 PFIndexes[i] = EltNo;
10277 if (isFourElementShuffle) {
10279 unsigned PFTableIndex = PFIndexes[0] * 9 * 9 * 9 + PFIndexes[1] * 9 * 9 +
10280 PFIndexes[2] * 9 + PFIndexes[3];
10283 unsigned Cost = (PFEntry >> 30);
10303 if (
V2.isUndef())
V2 = V1;
10305 return LowerVPERM(
Op, DAG, PermMask, VT, V1, V2);
10314 bool NeedSwap =
false;
10316 bool isPPC64 = Subtarget.
isPPC64();
10318 if (Subtarget.hasVSX() && Subtarget.hasP9Vector() &&
10320 LLVM_DEBUG(
dbgs() <<
"At least one of two input vectors are dead - using "
10321 "XXPERM instead\n");
10327 if ((!isLittleEndian && !
V2->hasOneUse() && V1->
hasOneUse()) ||
10328 (isLittleEndian && !V1->
hasOneUse() &&
V2->hasOneUse())) {
10330 NeedSwap = !NeedSwap;
10365 unsigned SrcElt = PermMask[i] < 0 ? 0 : PermMask[i];
10367 if (V1HasXXSWAPD) {
10370 else if (SrcElt < 16)
10373 if (V2HasXXSWAPD) {
10376 else if (SrcElt > 15)
10385 for (
unsigned j = 0;
j != BytesPerElement; ++
j)
10386 if (isLittleEndian)
10388 DAG.
getConstant(31 - (SrcElt * BytesPerElement + j), dl, MVT::i32));
10391 DAG.
getConstant(SrcElt * BytesPerElement + j, dl, MVT::i32));
10394 if (V1HasXXSWAPD) {
10398 if (V2HasXXSWAPD) {
10399 dl =
SDLoc(
V2->getOperand(0));
10400 V2 =
V2->getOperand(0)->getOperand(1);
10403 if (isPPC64 && (V1HasXXSWAPD || V2HasXXSWAPD)) {
10404 if (ValType != MVT::v2f64)
10406 if (
V2.getValueType() != MVT::v2f64)
10410 ShufflesHandledWithVPERM++;
10415 dbgs() <<
"Emitting a XXPERM for the following shuffle:\n";
10417 dbgs() <<
"Emitting a VPERM for the following shuffle:\n";
10420 dbgs() <<
"With the following permute control vector:\n";
10425 VPermMask = DAG.
getBitcast(MVT::v4i32, VPermMask);
10429 if (isLittleEndian)
10435 VPERMNode = DAG.
getBitcast(ValType, VPERMNode);
10447 switch (IntrinsicID) {
10451 case Intrinsic::ppc_altivec_vcmpbfp_p:
10455 case Intrinsic::ppc_altivec_vcmpeqfp_p:
10459 case Intrinsic::ppc_altivec_vcmpequb_p:
10463 case Intrinsic::ppc_altivec_vcmpequh_p:
10467 case Intrinsic::ppc_altivec_vcmpequw_p:
10471 case Intrinsic::ppc_altivec_vcmpequd_p:
10472 if (Subtarget.hasVSX() || Subtarget.hasP8Altivec()) {
10478 case Intrinsic::ppc_altivec_vcmpneb_p:
10479 case Intrinsic::ppc_altivec_vcmpneh_p:
10480 case Intrinsic::ppc_altivec_vcmpnew_p:
10481 case Intrinsic::ppc_altivec_vcmpnezb_p:
10482 case Intrinsic::ppc_altivec_vcmpnezh_p:
10483 case Intrinsic::ppc_altivec_vcmpnezw_p:
10484 if (Subtarget.hasP9Altivec()) {
10485 switch (IntrinsicID) {
10488 case Intrinsic::ppc_altivec_vcmpneb_p:
10491 case Intrinsic::ppc_altivec_vcmpneh_p:
10494 case Intrinsic::ppc_altivec_vcmpnew_p:
10497 case Intrinsic::ppc_altivec_vcmpnezb_p:
10500 case Intrinsic::ppc_altivec_vcmpnezh_p:
10503 case Intrinsic::ppc_altivec_vcmpnezw_p:
10511 case Intrinsic::ppc_altivec_vcmpgefp_p:
10515 case Intrinsic::ppc_altivec_vcmpgtfp_p:
10519 case Intrinsic::ppc_altivec_vcmpgtsb_p:
10523 case Intrinsic::ppc_altivec_vcmpgtsh_p:
10527 case Intrinsic::ppc_altivec_vcmpgtsw_p:
10531 case Intrinsic::ppc_altivec_vcmpgtsd_p:
10532 if (Subtarget.hasVSX() || Subtarget.hasP8Altivec()) {
10538 case Intrinsic::ppc_altivec_vcmpgtub_p:
10542 case Intrinsic::ppc_altivec_vcmpgtuh_p:
10546 case Intrinsic::ppc_altivec_vcmpgtuw_p:
10550 case Intrinsic::ppc_altivec_vcmpgtud_p:
10551 if (Subtarget.hasVSX() || Subtarget.hasP8Altivec()) {
10558 case Intrinsic::ppc_altivec_vcmpequq:
10559 case Intrinsic::ppc_altivec_vcmpgtsq:
10560 case Intrinsic::ppc_altivec_vcmpgtuq:
10561 if (!Subtarget.isISA3_1())
10563 switch (IntrinsicID) {
10566 case Intrinsic::ppc_altivec_vcmpequq:
10569 case Intrinsic::ppc_altivec_vcmpgtsq:
10572 case Intrinsic::ppc_altivec_vcmpgtuq:
10579 case Intrinsic::ppc_vsx_xvcmpeqdp_p:
10580 case Intrinsic::ppc_vsx_xvcmpgedp_p:
10581 case Intrinsic::ppc_vsx_xvcmpgtdp_p:
10582 case Intrinsic::ppc_vsx_xvcmpeqsp_p:
10583 case Intrinsic::ppc_vsx_xvcmpgesp_p:
10584 case Intrinsic::ppc_vsx_xvcmpgtsp_p:
10585 if (Subtarget.hasVSX()) {
10586 switch (IntrinsicID) {
10587 case Intrinsic::ppc_vsx_xvcmpeqdp_p:
10590 case Intrinsic::ppc_vsx_xvcmpgedp_p:
10593 case Intrinsic::ppc_vsx_xvcmpgtdp_p:
10596 case Intrinsic::ppc_vsx_xvcmpeqsp_p:
10599 case Intrinsic::ppc_vsx_xvcmpgesp_p:
10602 case Intrinsic::ppc_vsx_xvcmpgtsp_p:
10612 case Intrinsic::ppc_altivec_vcmpbfp:
10615 case Intrinsic::ppc_altivec_vcmpeqfp:
10618 case Intrinsic::ppc_altivec_vcmpequb:
10621 case Intrinsic::ppc_altivec_vcmpequh:
10624 case Intrinsic::ppc_altivec_vcmpequw:
10627 case Intrinsic::ppc_altivec_vcmpequd:
10628 if (Subtarget.hasP8Altivec())
10633 case Intrinsic::ppc_altivec_vcmpneb:
10634 case Intrinsic::ppc_altivec_vcmpneh:
10635 case Intrinsic::ppc_altivec_vcmpnew:
10636 case Intrinsic::ppc_altivec_vcmpnezb:
10637 case Intrinsic::ppc_altivec_vcmpnezh:
10638 case Intrinsic::ppc_altivec_vcmpnezw:
10639 if (Subtarget.hasP9Altivec())
10640 switch (IntrinsicID) {
10643 case Intrinsic::ppc_altivec_vcmpneb:
10646 case Intrinsic::ppc_altivec_vcmpneh:
10649 case Intrinsic::ppc_altivec_vcmpnew:
10652 case Intrinsic::ppc_altivec_vcmpnezb:
10655 case Intrinsic::ppc_altivec_vcmpnezh:
10658 case Intrinsic::ppc_altivec_vcmpnezw:
10665 case Intrinsic::ppc_altivec_vcmpgefp:
10668 case Intrinsic::ppc_altivec_vcmpgtfp:
10671 case Intrinsic::ppc_altivec_vcmpgtsb:
10674 case Intrinsic::ppc_altivec_vcmpgtsh:
10677 case Intrinsic::ppc_altivec_vcmpgtsw:
10680 case Intrinsic::ppc_altivec_vcmpgtsd:
10681 if (Subtarget.hasP8Altivec())
10686 case Intrinsic::ppc_altivec_vcmpgtub:
10689 case Intrinsic::ppc_altivec_vcmpgtuh:
10692 case Intrinsic::ppc_altivec_vcmpgtuw:
10695 case Intrinsic::ppc_altivec_vcmpgtud:
10696 if (Subtarget.hasP8Altivec())
10701 case Intrinsic::ppc_altivec_vcmpequq_p:
10702 case Intrinsic::ppc_altivec_vcmpgtsq_p:
10703 case Intrinsic::ppc_altivec_vcmpgtuq_p:
10704 if (!Subtarget.isISA3_1())
10706 switch (IntrinsicID) {
10709 case Intrinsic::ppc_altivec_vcmpequq_p:
10712 case Intrinsic::ppc_altivec_vcmpgtsq_p:
10715 case Intrinsic::ppc_altivec_vcmpgtuq_p:
10729 unsigned IntrinsicID =
Op.getConstantOperandVal(0);
10733 switch (IntrinsicID) {
10734 case Intrinsic::thread_pointer:
10740 case Intrinsic::ppc_mma_disassemble_acc: {
10741 if (Subtarget.isISAFuture()) {
10742 EVT ReturnTypes[] = {MVT::v256i1, MVT::v256i1};
10780 case Intrinsic::ppc_vsx_disassemble_pair: {
10783 if (IntrinsicID == Intrinsic::ppc_mma_disassemble_acc) {
10788 for (
int VecNo = 0; VecNo < NumVecs; VecNo++) {
10799 case Intrinsic::ppc_mma_xxmfacc:
10800 case Intrinsic::ppc_mma_xxmtacc: {
10802 if (!Subtarget.isISAFuture())
10813 case Intrinsic::ppc_unpack_longdouble: {
10814 auto *
Idx = dyn_cast<ConstantSDNode>(
Op.getOperand(2));
10815 assert(
Idx && (
Idx->getSExtValue() == 0 ||
Idx->getSExtValue() == 1) &&
10816 "Argument of long double unpack must be 0 or 1!");
10819 Idx->getValueType(0)));
10822 case Intrinsic::ppc_compare_exp_lt:
10823 case Intrinsic::ppc_compare_exp_gt:
10824 case Intrinsic::ppc_compare_exp_eq:
10825 case Intrinsic::ppc_compare_exp_uo: {
10827 switch (IntrinsicID) {
10828 case Intrinsic::ppc_compare_exp_lt:
10831 case Intrinsic::ppc_compare_exp_gt:
10834 case Intrinsic::ppc_compare_exp_eq:
10837 case Intrinsic::ppc_compare_exp_uo:
10843 PPC::SELECT_CC_I4, dl, MVT::i32,
10844 {SDValue(DAG.getMachineNode(PPC::XSCMPEXPDP, dl, MVT::i32,
10845 Op.getOperand(1), Op.getOperand(2)),
10847 DAG.getConstant(1, dl, MVT::i32), DAG.getConstant(0, dl, MVT::i32),
10848 DAG.getTargetConstant(Pred, dl, MVT::i32)}),
10851 case Intrinsic::ppc_test_data_class: {
10852 EVT OpVT =
Op.getOperand(1).getValueType();
10853 unsigned CmprOpc = OpVT == MVT::f128 ? PPC::XSTSTDCQP
10854 : (OpVT == MVT::f64 ? PPC::XSTSTDCDP
10858 PPC::SELECT_CC_I4, dl, MVT::i32,
10859 {SDValue(DAG.getMachineNode(CmprOpc, dl, MVT::i32, Op.getOperand(2),
10862 DAG.getConstant(1, dl, MVT::i32), DAG.getConstant(0, dl, MVT::i32),
10863 DAG.getTargetConstant(PPC::PRED_EQ, dl, MVT::i32)}),
10866 case Intrinsic::ppc_fnmsub: {
10867 EVT VT =
Op.getOperand(1).getValueType();
10868 if (!Subtarget.hasVSX() || (!Subtarget.hasFloat128() && VT == MVT::f128))
10874 Op.getOperand(2),
Op.getOperand(3));
10876 case Intrinsic::ppc_convert_f128_to_ppcf128:
10877 case Intrinsic::ppc_convert_ppcf128_to_f128: {
10878 RTLIB::Libcall LC = IntrinsicID == Intrinsic::ppc_convert_ppcf128_to_f128
10879 ? RTLIB::CONVERT_PPCF128_F128
10880 : RTLIB::CONVERT_F128_PPCF128;
10881 MakeLibCallOptions CallOptions;
10882 std::pair<SDValue, SDValue>
Result =
10883 makeLibCall(DAG, LC,
Op.getValueType(),
Op.getOperand(1), CallOptions,
10887 case Intrinsic::ppc_maxfe:
10888 case Intrinsic::ppc_maxfl:
10889 case Intrinsic::ppc_maxfs:
10890 case Intrinsic::ppc_minfe:
10891 case Intrinsic::ppc_minfl:
10892 case Intrinsic::ppc_minfs: {
10893 EVT VT =
Op.getValueType();
10896 [VT](
const SDUse &
Use) { return Use.getValueType() == VT; }) &&
10897 "ppc_[max|min]f[e|l|s] must have uniform type arguments");
10900 if (IntrinsicID == Intrinsic::ppc_minfe ||
10901 IntrinsicID == Intrinsic::ppc_minfl ||
10902 IntrinsicID == Intrinsic::ppc_minfs)
10924 Op.getOperand(1),
Op.getOperand(2),
10935 EVT VTs[] = {
Op.getOperand(2).getValueType(), MVT::Glue };
10947 switch (
Op.getConstantOperandVal(1)) {
10950 BitNo = 0; InvertBit =
false;
10953 BitNo = 0; InvertBit =
true;
10956 BitNo = 2; InvertBit =
false;
10959 BitNo = 2; InvertBit =
true;
10981 int ArgStart = isa<ConstantSDNode>(
Op.getOperand(0)) ? 0 : 1;
10983 switch (
Op.getConstantOperandVal(ArgStart)) {
10984 case Intrinsic::ppc_cfence: {
10985 assert(ArgStart == 1 &&
"llvm.ppc.cfence must carry a chain argument.");
10986 SDValue Val =
Op.getOperand(ArgStart + 1);
10988 if (Ty == MVT::i128) {
10993 unsigned Opcode = Subtarget.
isPPC64() ? PPC::CFENCE8 : PPC::CFENCE;
10994 EVT FTy = Subtarget.
isPPC64() ? MVT::i64 : MVT::i32;
11018 int VectorIndex = 0;
11031 "Expecting an atomic compare-and-swap here.");
11033 auto *AtomicNode = cast<AtomicSDNode>(
Op.getNode());
11034 EVT MemVT = AtomicNode->getMemoryVT();
11052 for (
int i = 0, e = AtomicNode->getNumOperands(); i <
e; i++)
11053 Ops.
push_back(AtomicNode->getOperand(i));
11065 EVT MemVT =
N->getMemoryVT();
11067 "Expect quadword atomic operations");
11069 unsigned Opc =
N->getOpcode();
11077 DAG.
getConstant(Intrinsic::ppc_atomic_load_i128, dl, MVT::i32)};
11078 for (
int I = 1,
E =
N->getNumOperands();
I <
E; ++
I)
11081 Ops, MemVT,
N->getMemOperand());
11088 DAG.
getNode(
ISD::OR, dl, {MVT::i128, MVT::Other}, {ValLo, ValHi});
11098 DAG.
getConstant(Intrinsic::ppc_atomic_store_i128, dl, MVT::i32)};
11108 N->getMemOperand());
11120 enum DataClassMask {
11122 DC_NEG_INF = 1 << 4,
11123 DC_POS_INF = 1 << 5,
11124 DC_NEG_ZERO = 1 << 2,
11125 DC_POS_ZERO = 1 << 3,
11126 DC_NEG_SUBNORM = 1,
11127 DC_POS_SUBNORM = 1 << 1,
11130 EVT VT =
Op.getValueType();
11132 unsigned TestOp = VT == MVT::f128 ? PPC::XSTSTDCQP
11133 : VT == MVT::f64 ? PPC::XSTSTDCDP
11144 return DAG.
getNOT(Dl, Rev, MVT::i1);
11151 TestOp, Dl, MVT::i32,
11153 DC_NEG_ZERO | DC_POS_ZERO |
11154 DC_NEG_SUBNORM | DC_POS_SUBNORM,
11160 DAG.
getMachineNode(TargetOpcode::EXTRACT_SUBREG, Dl, MVT::i1, Rev,
11166 TargetOpcode::EXTRACT_SUBREG, Dl, MVT::i1, Rev,
11171 Sign = DAG.
getNOT(Dl, Sign, MVT::i1);
11184 bool IsQuiet = Mask &
fcQNan;
11190 if (VT == MVT::f128) {
11194 QuietMask = 0x8000;
11195 }
else if (VT == MVT::f64) {
11207 QuietMask = 0x80000;
11208 }
else if (VT == MVT::f32) {
11210 QuietMask = 0x400000;
11226 unsigned NativeMask = 0;
11228 NativeMask |= DC_NAN;
11230 NativeMask |= DC_NEG_INF;
11232 NativeMask |= DC_POS_INF;
11234 NativeMask |= DC_NEG_ZERO;
11236 NativeMask |= DC_POS_ZERO;
11238 NativeMask |= DC_NEG_SUBNORM;
11240 NativeMask |= DC_POS_SUBNORM;
11243 TargetOpcode::EXTRACT_SUBREG, Dl, MVT::i1,
11245 TestOp, Dl, MVT::i32,
11254 assert(Subtarget.hasP9Vector() &&
"Test data class requires Power9");
11256 const auto *
RHS = cast<ConstantSDNode>(
Op.getOperand(1));
11281 "Should only be called for ISD::INSERT_VECTOR_ELT");
11285 EVT VT =
Op.getValueType();
11290 if (VT == MVT::v2f64 &&
C)
11293 if (Subtarget.hasP9Vector()) {
11302 if ((VT == MVT::v4f32) && (
V2.getValueType() == MVT::f32) &&
11303 (isa<LoadSDNode>(V2))) {
11308 BitcastLoad,
Op.getOperand(2));
11309 return DAG.
getBitcast(MVT::v4f32, InsVecElt);
11313 if (Subtarget.isISA3_1()) {
11314 if ((VT == MVT::v2i64 || VT == MVT::v2f64) && !Subtarget.
isPPC64())
11318 if (VT == MVT::v16i8 || VT == MVT::v8i16 || VT == MVT::v4i32 ||
11319 VT == MVT::v2i64 || VT == MVT::v4f32 || VT == MVT::v2f64)
11329 if (VT == MVT::v8i16 || VT == MVT::v16i8) {
11332 unsigned InsertAtElement =
C->getZExtValue();
11333 unsigned InsertAtByte = InsertAtElement * BytesInEachElement;
11335 InsertAtByte = (16 - BytesInEachElement) - InsertAtByte;
11349 EVT VT =
Op.getValueType();
11351 if (VT != MVT::v256i1 && VT != MVT::v512i1)
11357 assert((VT != MVT::v512i1 || Subtarget.hasMMA()) &&
11358 "Type unsupported without MMA");
11359 assert((VT != MVT::v256i1 || Subtarget.pairedVectorMemops()) &&
11360 "Type unsupported without paired vector support");
11365 for (
unsigned Idx = 0;
Idx < NumVecs; ++
Idx) {
11367 DAG.
getLoad(MVT::v16i8, dl, LoadChain, BasePtr,
11377 std::reverse(Loads.
begin(), Loads.
end());
11378 std::reverse(LoadChains.
begin(), LoadChains.
end());
11396 EVT StoreVT =
Value.getValueType();
11398 if (StoreVT != MVT::v256i1 && StoreVT != MVT::v512i1)
11404 assert((StoreVT != MVT::v512i1 || Subtarget.hasMMA()) &&
11405 "Type unsupported without MMA");
11406 assert((StoreVT != MVT::v256i1 || Subtarget.pairedVectorMemops()) &&
11407 "Type unsupported without paired vector support");
11410 unsigned NumVecs = 2;
11411 if (StoreVT == MVT::v512i1) {
11412 if (Subtarget.isISAFuture()) {
11413 EVT ReturnTypes[] = {MVT::v256i1, MVT::v256i1};
11415 PPC::DMXXEXTFDMR512, dl,
ArrayRef(ReturnTypes, 2),
Op.getOperand(1));
11418 Value2 =
SDValue(ExtNode, 1);
11423 for (
unsigned Idx = 0;
Idx < NumVecs; ++
Idx) {
11426 if (Subtarget.isISAFuture()) {
11436 DAG.
getStore(StoreChain, dl, Elt, BasePtr,
11450 if (
Op.getValueType() == MVT::v4i32) {
11467 LHS, RHS, DAG, dl, MVT::v4i32);
11470 LHS, RHSSwap, Zero, DAG, dl, MVT::v4i32);
11475 }
else if (
Op.getValueType() == MVT::v16i8) {
11481 LHS, RHS, DAG, dl, MVT::v8i16);
11486 LHS, RHS, DAG, dl, MVT::v8i16);
11494 for (
unsigned i = 0; i != 8; ++i) {
11495 if (isLittleEndian) {
11497 Ops[i*2+1] = 2*i+16;
11500 Ops[i*2+1] = 2*i+1+16;
11503 if (isLittleEndian)
11513 bool IsStrict =
Op->isStrictFPOpcode();
11514 if (
Op.getOperand(IsStrict ? 1 : 0).getValueType() == MVT::f128 &&
11515 !Subtarget.hasP9Vector())
11525 "Should only be called for ISD::FP_EXTEND");
11529 if (
Op.getValueType() != MVT::v2f64 ||
11530 Op.getOperand(0).getValueType() != MVT::v2f32)
11542 "Node should have 2 operands with second one being a constant!");
11554 int DWord =
Idx >> 1;
11577 LD->getMemoryVT(),
LD->getMemOperand());
11590 LD->getMemoryVT(),
LD->getMemOperand());
11601 switch (
Op.getOpcode()) {
11630 return LowerGET_DYNAMIC_AREA_OFFSET(
Op, DAG);
11656 case ISD::FSHL:
return LowerFunnelShift(
Op, DAG);
11657 case ISD::FSHR:
return LowerFunnelShift(
Op, DAG);
11669 return LowerFP_ROUND(
Op, DAG);
11682 return LowerINTRINSIC_VOID(
Op, DAG);
11684 return LowerBSWAP(
Op, DAG);
11686 return LowerATOMIC_CMP_SWAP(
Op, DAG);
11688 return LowerATOMIC_LOAD_STORE(
Op, DAG);
11690 return LowerIS_FPCLASS(
Op, DAG);
11698 switch (
N->getOpcode()) {
11700 llvm_unreachable(
"Do not know how to custom type legalize this operation!");
11717 if (
N->getConstantOperandVal(1) != Intrinsic::loop_decrement)
11720 assert(
N->getValueType(0) == MVT::i1 &&
11721 "Unexpected result type for CTR decrement intrinsic");
11723 N->getValueType(0));
11733 switch (
N->getConstantOperandVal(0)) {
11734 case Intrinsic::ppc_pack_longdouble:
11736 N->getOperand(2),
N->getOperand(1)));
11738 case Intrinsic::ppc_maxfe:
11739 case Intrinsic::ppc_minfe:
11740 case Intrinsic::ppc_fnmsub:
11741 case Intrinsic::ppc_convert_f128_to_ppcf128:
11751 EVT VT =
N->getValueType(0);
11753 if (VT == MVT::i64) {
11766 if (
N->getOperand(
N->isStrictFPOpcode() ? 1 : 0).getValueType() ==
11770 Results.push_back(LoweredValue);
11771 if (
N->isStrictFPOpcode())
11776 if (!
N->getValueType(0).isVector())
11827 if (isa<LoadInst>(Inst))
11831 Intrinsic::ppc_cfence, {Inst->getType()}),
11841 unsigned AtomicSize,
11842 unsigned BinOpcode,
11843 unsigned CmpOpcode,
11844 unsigned CmpPred)
const {
11848 auto LoadMnemonic = PPC::LDARX;
11849 auto StoreMnemonic = PPC::STDCX;
11850 switch (AtomicSize) {
11854 LoadMnemonic = PPC::LBARX;
11855 StoreMnemonic = PPC::STBCX;
11856 assert(Subtarget.hasPartwordAtomics() &&
"Call this only with size >=4");
11859 LoadMnemonic = PPC::LHARX;
11860 StoreMnemonic = PPC::STHCX;
11861 assert(Subtarget.hasPartwordAtomics() &&
"Call this only with size >=4");
11864 LoadMnemonic = PPC::LWARX;
11865 StoreMnemonic = PPC::STWCX;
11868 LoadMnemonic = PPC::LDARX;
11869 StoreMnemonic = PPC::STDCX;
11885 CmpOpcode ?
F->CreateMachineBasicBlock(LLVM_BB) :
nullptr;
11887 F->insert(It, loopMBB);
11889 F->insert(It, loop2MBB);
11890 F->insert(It, exitMBB);
11896 Register TmpReg = (!BinOpcode) ? incr :
11898 : &PPC::GPRCRegClass);
11923 BuildMI(BB, dl,
TII->get(LoadMnemonic), dest)
11930 if (CmpOpcode == PPC::CMPW && AtomicSize < 4) {
11932 BuildMI(BB, dl,
TII->get(AtomicSize == 1 ? PPC::EXTSB : PPC::EXTSH),
11960 switch(
MI.getOpcode()) {
11964 return TII->isSignExtended(
MI.getOperand(1).getReg(),
11965 &
MI.getMF()->getRegInfo());
11989 case PPC::EXTSB8_32_64:
11990 case PPC::EXTSB8_rec:
11991 case PPC::EXTSB_rec:
11994 case PPC::EXTSH8_32_64:
11995 case PPC::EXTSH8_rec:
11996 case PPC::EXTSH_rec:
11998 case PPC::EXTSWSLI:
11999 case PPC::EXTSWSLI_32_64:
12000 case PPC::EXTSWSLI_32_64_rec:
12001 case PPC::EXTSWSLI_rec:
12002 case PPC::EXTSW_32:
12003 case PPC::EXTSW_32_64:
12004 case PPC::EXTSW_32_64_rec:
12005 case PPC::EXTSW_rec:
12008 case PPC::SRAWI_rec:
12009 case PPC::SRAW_rec:
12018 unsigned BinOpcode,
unsigned CmpOpcode,
unsigned CmpPred)
const {
12028 bool IsSignExtended =
12031 if (CmpOpcode == PPC::CMPW && !IsSignExtended) {
12033 BuildMI(*BB,
MI, dl,
TII->get(is8bit ? PPC::EXTSB : PPC::EXTSH), ValueReg)
12034 .
addReg(
MI.getOperand(3).getReg());
12035 MI.getOperand(3).setReg(ValueReg);
12039 if (Subtarget.hasPartwordAtomics())
12047 bool is64bit = Subtarget.
isPPC64();
12049 unsigned ZeroReg = is64bit ? PPC::ZERO8 : PPC::ZERO;
12060 CmpOpcode ?
F->CreateMachineBasicBlock(LLVM_BB) :
nullptr;
12062 F->insert(It, loopMBB);
12064 F->insert(It, loop2MBB);
12065 F->insert(It, exitMBB);
12071 is64bit ? &PPC::G8RCRegClass : &PPC::GPRCRegClass;
12116 if (ptrA != ZeroReg) {
12118 BuildMI(BB, dl,
TII->get(is64bit ? PPC::ADD8 : PPC::ADD4), Ptr1Reg)
12126 BuildMI(BB, dl,
TII->get(PPC::RLWINM), Shift1Reg)
12127 .
addReg(Ptr1Reg, 0, is64bit ? PPC::sub_32 : 0)
12130 .
addImm(is8bit ? 28 : 27);
12131 if (!isLittleEndian)
12132 BuildMI(BB, dl,
TII->get(PPC::XORI), ShiftReg)
12134 .
addImm(is8bit ? 24 : 16);
12136 BuildMI(BB, dl,
TII->get(PPC::RLDICR), PtrReg)
12141 BuildMI(BB, dl,
TII->get(PPC::RLWINM), PtrReg)
12151 BuildMI(BB, dl,
TII->get(PPC::ORI), Mask2Reg)
12155 BuildMI(BB, dl,
TII->get(PPC::SLW), MaskReg)
12160 BuildMI(BB, dl,
TII->get(PPC::LWARX), TmpDestReg)
12164 BuildMI(BB, dl,
TII->get(BinOpcode), TmpReg)
12167 BuildMI(BB, dl,
TII->get(PPC::ANDC), Tmp2Reg)
12179 unsigned ValueReg = SReg;
12180 unsigned CmpReg = Incr2Reg;
12181 if (CmpOpcode == PPC::CMPW) {
12183 BuildMI(BB, dl,
TII->get(PPC::SRW), ValueReg)
12187 BuildMI(BB, dl,
TII->get(is8bit ? PPC::EXTSB : PPC::EXTSH), ValueSReg)
12189 ValueReg = ValueSReg;
12221 .
addImm(is8bit ? 24 : 16)
12242 Register DstReg =
MI.getOperand(0).getReg();
12244 assert(
TRI->isTypeLegalForClass(*RC, MVT::i32) &&
"Invalid destination!");
12245 Register mainDstReg =
MRI.createVirtualRegister(RC);
12246 Register restoreDstReg =
MRI.createVirtualRegister(RC);
12249 assert((PVT == MVT::i64 || PVT == MVT::i32) &&
12250 "Invalid Pointer Size!");
12298 Register LabelReg =
MRI.createVirtualRegister(PtrRC);
12299 Register BufReg =
MI.getOperand(1).getReg();
12314 BaseReg = Subtarget.
isPPC64() ? PPC::X1 : PPC::R1;
12316 BaseReg = Subtarget.
isPPC64() ? PPC::BP8 : PPC::BP;
12319 TII->get(Subtarget.
isPPC64() ? PPC::STD : PPC::STW))
12342 TII->get(Subtarget.
isPPC64() ? PPC::MFLR8 : PPC::MFLR), LabelReg);
12363 TII->get(PPC::PHI), DstReg)
12367 MI.eraseFromParent();
12381 assert((PVT == MVT::i64 || PVT == MVT::i32) &&
12382 "Invalid Pointer Size!");
12385 (PVT == MVT::i64) ? &PPC::G8RCRegClass : &PPC::GPRCRegClass;
12388 unsigned FP = (PVT == MVT::i64) ? PPC::X31 : PPC::R31;
12389 unsigned SP = (PVT == MVT::i64) ? PPC::X1 : PPC::R1;
12403 Register BufReg =
MI.getOperand(0).getReg();
12408 if (PVT == MVT::i64) {
12420 if (PVT == MVT::i64) {
12432 if (PVT == MVT::i64) {
12444 if (PVT == MVT::i64) {
12456 if (PVT == MVT::i64 && Subtarget.
isSVR4ABI()) {
12466 TII->get(PVT == MVT::i64 ? PPC::MTCTR8 : PPC::MTCTR)).
addReg(Tmp);
12469 MI.eraseFromParent();
12485 "Unexpected stack alignment");
12489 unsigned StackProbeSize =
12492 StackProbeSize &= ~(StackAlign - 1);
12493 return StackProbeSize ? StackProbeSize : StackAlign;
12505 const bool isPPC64 = Subtarget.
isPPC64();
12537 MF->
insert(MBBIter, TestMBB);
12538 MF->
insert(MBBIter, BlockMBB);
12539 MF->
insert(MBBIter, TailMBB);
12544 Register DstReg =
MI.getOperand(0).getReg();
12545 Register NegSizeReg =
MI.getOperand(1).getReg();
12546 Register SPReg = isPPC64 ? PPC::X1 : PPC::R1;
12547 Register FinalStackPtr =
MRI.createVirtualRegister(isPPC64 ? G8RC : GPRC);
12548 Register FramePointer =
MRI.createVirtualRegister(isPPC64 ? G8RC : GPRC);
12549 Register ActualNegSizeReg =
MRI.createVirtualRegister(isPPC64 ? G8RC : GPRC);
12555 if (!
MRI.hasOneNonDBGUse(NegSizeReg))
12557 isPPC64 ? PPC::PREPARE_PROBED_ALLOCA_64 : PPC::PREPARE_PROBED_ALLOCA_32;
12563 ProbeOpc = isPPC64 ? PPC::PREPARE_PROBED_ALLOCA_NEGSIZE_SAME_REG_64
12564 : PPC::PREPARE_PROBED_ALLOCA_NEGSIZE_SAME_REG_32;
12566 .
addDef(ActualNegSizeReg)
12568 .
add(
MI.getOperand(2))
12569 .
add(
MI.getOperand(3));
12575 .
addReg(ActualNegSizeReg);
12578 int64_t NegProbeSize = -(int64_t)ProbeSize;
12579 assert(isInt<32>(NegProbeSize) &&
"Unhandled probe size!");
12580 Register ScratchReg =
MRI.createVirtualRegister(isPPC64 ? G8RC : GPRC);
12581 if (!isInt<16>(NegProbeSize)) {
12582 Register TempReg =
MRI.createVirtualRegister(isPPC64 ? G8RC : GPRC);
12584 .
addImm(NegProbeSize >> 16);
12588 .
addImm(NegProbeSize & 0xFFFF);
12595 Register Div =
MRI.createVirtualRegister(isPPC64 ? G8RC : GPRC);
12597 .
addReg(ActualNegSizeReg)
12599 Register Mul =
MRI.createVirtualRegister(isPPC64 ? G8RC : GPRC);
12603 Register NegMod =
MRI.createVirtualRegister(isPPC64 ? G8RC : GPRC);
12606 .
addReg(ActualNegSizeReg);
12615 Register CmpResult =
MRI.createVirtualRegister(&PPC::CRRCRegClass);
12616 BuildMI(TestMBB,
DL,
TII->get(isPPC64 ? PPC::CMPD : PPC::CMPW), CmpResult)
12630 BuildMI(BlockMBB,
DL,
TII->get(isPPC64 ? PPC::STDUX : PPC::STWUX), SPReg)
12641 MRI.createVirtualRegister(isPPC64 ? G8RC : GPRC);
12643 TII->get(isPPC64 ? PPC::DYNAREAOFFSET8 : PPC::DYNAREAOFFSET),
12644 MaxCallFrameSizeReg)
12645 .
add(
MI.getOperand(2))
12646 .
add(
MI.getOperand(3));
12647 BuildMI(TailMBB,
DL,
TII->get(isPPC64 ? PPC::ADD8 : PPC::ADD4), DstReg)
12649 .
addReg(MaxCallFrameSizeReg);
12658 MI.eraseFromParent();
12660 ++NumDynamicAllocaProbed;
12667 if (
MI.getOpcode() == TargetOpcode::STACKMAP ||
12668 MI.getOpcode() == TargetOpcode::PATCHPOINT) {
12670 MI.getOpcode() == TargetOpcode::PATCHPOINT &&
12683 if (
MI.getOpcode() == PPC::EH_SjLj_SetJmp32 ||
12684 MI.getOpcode() == PPC::EH_SjLj_SetJmp64) {
12686 }
else if (
MI.getOpcode() == PPC::EH_SjLj_LongJmp32 ||
12687 MI.getOpcode() == PPC::EH_SjLj_LongJmp64) {
12701 if (
MI.getOpcode() == PPC::SELECT_CC_I4 ||
12702 MI.getOpcode() == PPC::SELECT_CC_I8 ||
MI.getOpcode() == PPC::SELECT_I4 ||
12703 MI.getOpcode() == PPC::SELECT_I8) {
12705 if (
MI.getOpcode() == PPC::SELECT_CC_I4 ||
12706 MI.getOpcode() == PPC::SELECT_CC_I8)
12707 Cond.push_back(
MI.getOperand(4));
12710 Cond.push_back(
MI.getOperand(1));
12713 TII->insertSelect(*BB,
MI, dl,
MI.getOperand(0).getReg(),
Cond,
12714 MI.getOperand(2).getReg(),
MI.getOperand(3).getReg());
12715 }
else if (
MI.getOpcode() == PPC::SELECT_CC_F4 ||
12716 MI.getOpcode() == PPC::SELECT_CC_F8 ||
12717 MI.getOpcode() == PPC::SELECT_CC_F16 ||
12718 MI.getOpcode() == PPC::SELECT_CC_VRRC ||
12719 MI.getOpcode() == PPC::SELECT_CC_VSFRC ||
12720 MI.getOpcode() == PPC::SELECT_CC_VSSRC ||
12721 MI.getOpcode() == PPC::SELECT_CC_VSRC ||
12722 MI.getOpcode() == PPC::SELECT_CC_SPE4 ||
12723 MI.getOpcode() == PPC::SELECT_CC_SPE ||
12724 MI.getOpcode() == PPC::SELECT_F4 ||
12725 MI.getOpcode() == PPC::SELECT_F8 ||
12726 MI.getOpcode() == PPC::SELECT_F16 ||
12727 MI.getOpcode() == PPC::SELECT_SPE ||
12728 MI.getOpcode() == PPC::SELECT_SPE4 ||
12729 MI.getOpcode() == PPC::SELECT_VRRC ||
12730 MI.getOpcode() == PPC::SELECT_VSFRC ||
12731 MI.getOpcode() == PPC::SELECT_VSSRC ||
12732 MI.getOpcode() == PPC::SELECT_VSRC) {
12747 F->insert(It, copy0MBB);
12748 F->insert(It, sinkMBB);
12759 if (
MI.getOpcode() == PPC::SELECT_I4 ||
MI.getOpcode() == PPC::SELECT_I8 ||
12760 MI.getOpcode() == PPC::SELECT_F4 ||
MI.getOpcode() == PPC::SELECT_F8 ||
12761 MI.getOpcode() == PPC::SELECT_F16 ||
12762 MI.getOpcode() == PPC::SELECT_SPE4 ||
12763 MI.getOpcode() == PPC::SELECT_SPE ||
12764 MI.getOpcode() == PPC::SELECT_VRRC ||
12765 MI.getOpcode() == PPC::SELECT_VSFRC ||
12766 MI.getOpcode() == PPC::SELECT_VSSRC ||
12767 MI.getOpcode() == PPC::SELECT_VSRC) {
12769 .
addReg(
MI.getOperand(1).getReg())
12772 unsigned SelectPred =
MI.getOperand(4).getImm();
12775 .
addReg(
MI.getOperand(1).getReg())
12792 .
addReg(
MI.getOperand(3).getReg())
12794 .
addReg(
MI.getOperand(2).getReg())
12796 }
else if (
MI.getOpcode() == PPC::ReadTB) {
12812 F->insert(It, readMBB);
12813 F->insert(It, sinkMBB);
12834 BuildMI(BB, dl,
TII->get(PPC::CMPW), CmpReg)
12844 }
else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_ADD_I8)
12846 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_ADD_I16)
12848 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_ADD_I32)
12850 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_ADD_I64)
12853 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_AND_I8)
12855 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_AND_I16)
12857 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_AND_I32)
12859 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_AND_I64)
12862 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_OR_I8)
12864 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_OR_I16)
12866 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_OR_I32)
12868 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_OR_I64)
12871 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_XOR_I8)
12873 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_XOR_I16)
12875 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_XOR_I32)
12877 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_XOR_I64)
12880 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_NAND_I8)
12882 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_NAND_I16)
12884 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_NAND_I32)
12886 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_NAND_I64)
12889 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_SUB_I8)
12891 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_SUB_I16)
12893 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_SUB_I32)
12895 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_SUB_I64)
12898 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_MIN_I8)
12900 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_MIN_I16)
12902 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_MIN_I32)
12904 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_MIN_I64)
12907 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_MAX_I8)
12909 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_MAX_I16)
12911 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_MAX_I32)
12913 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_MAX_I64)
12916 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_UMIN_I8)
12918 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_UMIN_I16)
12920 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_UMIN_I32)
12922 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_UMIN_I64)
12925 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_UMAX_I8)
12927 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_UMAX_I16)
12929 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_UMAX_I32)
12931 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_UMAX_I64)
12934 else if (
MI.getOpcode() == PPC::ATOMIC_SWAP_I8)
12936 else if (
MI.getOpcode() == PPC::ATOMIC_SWAP_I16)
12938 else if (
MI.getOpcode() == PPC::ATOMIC_SWAP_I32)
12940 else if (
MI.getOpcode() == PPC::ATOMIC_SWAP_I64)
12942 else if (
MI.getOpcode() == PPC::ATOMIC_CMP_SWAP_I32 ||
12943 MI.getOpcode() == PPC::ATOMIC_CMP_SWAP_I64 ||
12944 (Subtarget.hasPartwordAtomics() &&
12945 MI.getOpcode() == PPC::ATOMIC_CMP_SWAP_I8) ||
12946 (Subtarget.hasPartwordAtomics() &&
12947 MI.getOpcode() == PPC::ATOMIC_CMP_SWAP_I16)) {
12948 bool is64bit =
MI.getOpcode() == PPC::ATOMIC_CMP_SWAP_I64;
12950 auto LoadMnemonic = PPC::LDARX;
12951 auto StoreMnemonic = PPC::STDCX;
12952 switch (
MI.getOpcode()) {
12955 case PPC::ATOMIC_CMP_SWAP_I8:
12956 LoadMnemonic = PPC::LBARX;
12957 StoreMnemonic = PPC::STBCX;
12958 assert(Subtarget.hasPartwordAtomics() &&
"No support partword atomics.");
12960 case PPC::ATOMIC_CMP_SWAP_I16:
12961 LoadMnemonic = PPC::LHARX;
12962 StoreMnemonic = PPC::STHCX;
12963 assert(Subtarget.hasPartwordAtomics() &&
"No support partword atomics.");
12965 case PPC::ATOMIC_CMP_SWAP_I32:
12966 LoadMnemonic = PPC::LWARX;
12967 StoreMnemonic = PPC::STWCX;
12969 case PPC::ATOMIC_CMP_SWAP_I64:
12970 LoadMnemonic = PPC::LDARX;
12971 StoreMnemonic = PPC::STDCX;
12979 Register oldval =
MI.getOperand(3).getReg();
12980 Register newval =
MI.getOperand(4).getReg();
12986 F->insert(It, loop1MBB);
12987 F->insert(It, loop2MBB);
12988 F->insert(It, exitMBB);
13009 BuildMI(BB, dl,
TII->get(is64bit ? PPC::CMPD : PPC::CMPW), CrReg)
13035 }
else if (
MI.getOpcode() == PPC::ATOMIC_CMP_SWAP_I8 ||
13036 MI.getOpcode() == PPC::ATOMIC_CMP_SWAP_I16) {
13040 bool is64bit = Subtarget.
isPPC64();
13042 bool is8bit =
MI.getOpcode() == PPC::ATOMIC_CMP_SWAP_I8;
13047 Register oldval =
MI.getOperand(3).getReg();
13048 Register newval =
MI.getOperand(4).getReg();
13054 F->insert(It, loop1MBB);
13055 F->insert(It, loop2MBB);
13056 F->insert(It, exitMBB);
13063 is64bit ? &PPC::G8RCRegClass : &PPC::GPRCRegClass;
13082 Register ZeroReg = is64bit ? PPC::ZERO8 : PPC::ZERO;
13114 if (ptrA != ZeroReg) {
13116 BuildMI(BB, dl,
TII->get(is64bit ? PPC::ADD8 : PPC::ADD4), Ptr1Reg)
13125 BuildMI(BB, dl,
TII->get(PPC::RLWINM), Shift1Reg)
13126 .
addReg(Ptr1Reg, 0, is64bit ? PPC::sub_32 : 0)
13129 .
addImm(is8bit ? 28 : 27);
13130 if (!isLittleEndian)
13131 BuildMI(BB, dl,
TII->get(PPC::XORI), ShiftReg)
13133 .
addImm(is8bit ? 24 : 16);
13135 BuildMI(BB, dl,
TII->get(PPC::RLDICR), PtrReg)
13140 BuildMI(BB, dl,
TII->get(PPC::RLWINM), PtrReg)
13145 BuildMI(BB, dl,
TII->get(PPC::SLW), NewVal2Reg)
13148 BuildMI(BB, dl,
TII->get(PPC::SLW), OldVal2Reg)
13155 BuildMI(BB, dl,
TII->get(PPC::ORI), Mask2Reg)
13159 BuildMI(BB, dl,
TII->get(PPC::SLW), MaskReg)
13162 BuildMI(BB, dl,
TII->get(PPC::AND), NewVal3Reg)
13165 BuildMI(BB, dl,
TII->get(PPC::AND), OldVal3Reg)
13170 BuildMI(BB, dl,
TII->get(PPC::LWARX), TmpDestReg)
13187 BuildMI(BB, dl,
TII->get(PPC::ANDC), Tmp2Reg)
13211 }
else if (
MI.getOpcode() == PPC::FADDrtz) {
13236 auto MIB =
BuildMI(*BB,
MI, dl,
TII->get(PPC::FADD), Dest)
13244 }
else if (
MI.getOpcode() == PPC::ANDI_rec_1_EQ_BIT ||
13245 MI.getOpcode() == PPC::ANDI_rec_1_GT_BIT ||
13246 MI.getOpcode() == PPC::ANDI_rec_1_EQ_BIT8 ||
13247 MI.getOpcode() == PPC::ANDI_rec_1_GT_BIT8) {
13248 unsigned Opcode = (
MI.getOpcode() == PPC::ANDI_rec_1_EQ_BIT8 ||
13249 MI.getOpcode() == PPC::ANDI_rec_1_GT_BIT8)
13252 bool IsEQ = (
MI.getOpcode() == PPC::ANDI_rec_1_EQ_BIT ||
13253 MI.getOpcode() == PPC::ANDI_rec_1_EQ_BIT8);
13257 Opcode == PPC::ANDI_rec ? &PPC::GPRCRegClass : &PPC::G8RCRegClass);
13261 .
addReg(
MI.getOperand(1).getReg())
13264 MI.getOperand(0).getReg())
13265 .
addReg(IsEQ ? PPC::CR0EQ : PPC::CR0GT);
13266 }
else if (
MI.getOpcode() == PPC::TCHECK_RET) {
13272 MI.getOperand(0).getReg())
13274 }
else if (
MI.getOpcode() == PPC::TBEGIN_RET) {
13276 unsigned Imm =
MI.getOperand(1).getImm();
13279 MI.getOperand(0).getReg())
13281 }
else if (
MI.getOpcode() == PPC::SETRNDi) {
13283 Register OldFPSCRReg =
MI.getOperand(0).getReg();
13286 if (
MRI.use_empty(OldFPSCRReg))
13287 BuildMI(*BB,
MI, dl,
TII->get(TargetOpcode::IMPLICIT_DEF), OldFPSCRReg);
13289 BuildMI(*BB,
MI, dl,
TII->get(PPC::MFFS), OldFPSCRReg);
13300 unsigned Mode =
MI.getOperand(1).getImm();
13301 BuildMI(*BB,
MI, dl,
TII->get((Mode & 1) ? PPC::MTFSB1 : PPC::MTFSB0))
13305 BuildMI(*BB,
MI, dl,
TII->get((Mode & 2) ? PPC::MTFSB1 : PPC::MTFSB0))
13308 }
else if (
MI.getOpcode() == PPC::SETRND) {
13316 auto copyRegFromG8RCOrF8RC = [&] (
unsigned DestReg,
unsigned SrcReg) {
13317 if (Subtarget.hasDirectMove()) {
13318 BuildMI(*BB,
MI, dl,
TII->get(TargetOpcode::COPY), DestReg)
13322 unsigned StoreOp = PPC::STD, LoadOp = PPC::LFD;
13325 if (RC == &PPC::F8RCRegClass) {
13328 "Unsupported RegClass.");
13330 StoreOp = PPC::STFD;
13335 (RegInfo.
getRegClass(DestReg) == &PPC::F8RCRegClass) &&
13336 "Unsupported RegClass.");
13369 Register OldFPSCRReg =
MI.getOperand(0).getReg();
13372 BuildMI(*BB,
MI, dl,
TII->get(PPC::MFFS), OldFPSCRReg);
13386 copyRegFromG8RCOrF8RC(OldFPSCRTmpReg, OldFPSCRReg);
13394 BuildMI(*BB,
MI, dl,
TII->get(TargetOpcode::IMPLICIT_DEF), ImDefReg);
13395 BuildMI(*BB,
MI, dl,
TII->get(PPC::INSERT_SUBREG), ExtSrcReg)
13401 BuildMI(*BB,
MI, dl,
TII->get(PPC::RLDIMI), NewFPSCRTmpReg)
13408 copyRegFromG8RCOrF8RC(NewFPSCRReg, NewFPSCRTmpReg);
13417 }
else if (
MI.getOpcode() == PPC::SETFLM) {
13421 Register OldFPSCRReg =
MI.getOperand(0).getReg();
13422 if (
MRI.use_empty(OldFPSCRReg))
13423 BuildMI(*BB,
MI, Dl,
TII->get(TargetOpcode::IMPLICIT_DEF), OldFPSCRReg);
13425 BuildMI(*BB,
MI, Dl,
TII->get(PPC::MFFS), OldFPSCRReg);
13428 Register NewFPSCRReg =
MI.getOperand(1).getReg();
13434 }
else if (
MI.getOpcode() == PPC::PROBED_ALLOCA_32 ||
13435 MI.getOpcode() == PPC::PROBED_ALLOCA_64) {
13437 }
else if (
MI.getOpcode() == PPC::SPLIT_QUADWORD) {
13444 .
addUse(Src, 0, PPC::sub_gp8_x1);
13447 .
addUse(Src, 0, PPC::sub_gp8_x0);
13448 }
else if (
MI.getOpcode() == PPC::LQX_PSEUDO ||
13449 MI.getOpcode() == PPC::STQX_PSEUDO) {
13455 F->getRegInfo().createVirtualRegister(&PPC::G8RC_and_G8RC_NOX0RegClass);
13461 MI.getOpcode() == PPC::LQX_PSEUDO ?
TII->get(PPC::LQ)
13462 :
TII->get(PPC::STQ))
13470 MI.eraseFromParent();
13483 int RefinementSteps = Subtarget.hasRecipPrec() ? 1 : 3;
13486 return RefinementSteps;
13492 EVT VT =
Op.getValueType();
13495 ((VT != MVT::v2f64 && VT != MVT::v4f32) || !Subtarget.hasVSX())))
13519PPCTargetLowering::getSqrtResultForDenormInput(
SDValue Op,
13522 EVT VT =
Op.getValueType();
13523 if (VT != MVT::f64 &&
13524 ((VT != MVT::v2f64 && VT != MVT::v4f32) || !Subtarget.hasVSX()))
13531 int Enabled,
int &RefinementSteps,
13532 bool &UseOneConstNR,
13533 bool Reciprocal)
const {
13535 if ((VT == MVT::f32 && Subtarget.hasFRSQRTES()) ||
13536 (VT == MVT::f64 && Subtarget.hasFRSQRTE()) ||
13537 (VT == MVT::v4f32 && Subtarget.hasAltivec()) ||
13538 (VT == MVT::v2f64 && Subtarget.hasVSX())) {
13544 UseOneConstNR = !Subtarget.needsTwoConstNR();
13552 int &RefinementSteps)
const {
13554 if ((VT == MVT::f32 && Subtarget.hasFRES()) ||
13555 (VT == MVT::f64 && Subtarget.hasFRE()) ||
13556 (VT == MVT::v4f32 && Subtarget.hasAltivec()) ||
13557 (VT == MVT::v2f64 && Subtarget.hasVSX())) {
13565unsigned PPCTargetLowering::combineRepeatedFPDivisors()
const {
13603 unsigned Bytes,
int Dist,
13613 int FI = cast<FrameIndexSDNode>(Loc)->getIndex();
13614 int BFI = cast<FrameIndexSDNode>(BaseLoc)->getIndex();
13617 if (FS != BFS || FS != (
int)Bytes)
return false;
13621 SDValue Base1 = Loc, Base2 = BaseLoc;
13622 int64_t Offset1 = 0, Offset2 = 0;
13625 if (Base1 == Base2 && Offset1 == (Offset2 + Dist * Bytes))
13635 if (isGA1 && isGA2 && GV1 == GV2)
13636 return Offset1 == (Offset2 + Dist*Bytes);
13643 unsigned Bytes,
int Dist,
13646 EVT VT = LS->getMemoryVT();
13647 SDValue Loc = LS->getBasePtr();
13653 switch (
N->getConstantOperandVal(1)) {
13654 default:
return false;
13655 case Intrinsic::ppc_altivec_lvx:
13656 case Intrinsic::ppc_altivec_lvxl:
13657 case Intrinsic::ppc_vsx_lxvw4x:
13658 case Intrinsic::ppc_vsx_lxvw4x_be:
13661 case Intrinsic::ppc_vsx_lxvd2x:
13662 case Intrinsic::ppc_vsx_lxvd2x_be:
13665 case Intrinsic::ppc_altivec_lvebx:
13668 case Intrinsic::ppc_altivec_lvehx:
13671 case Intrinsic::ppc_altivec_lvewx:
13681 switch (
N->getConstantOperandVal(1)) {
13682 default:
return false;
13683 case Intrinsic::ppc_altivec_stvx:
13684 case Intrinsic::ppc_altivec_stvxl:
13685 case Intrinsic::ppc_vsx_stxvw4x:
13688 case Intrinsic::ppc_vsx_stxvd2x:
13691 case Intrinsic::ppc_vsx_stxvw4x_be:
13694 case Intrinsic::ppc_vsx_stxvd2x_be:
13697 case Intrinsic::ppc_altivec_stvebx:
13700 case Intrinsic::ppc_altivec_stvehx:
13703 case Intrinsic::ppc_altivec_stvewx:
13720 SDValue Chain = LD->getChain();
13721 EVT VT = LD->getMemoryVT();
13730 while (!Queue.empty()) {
13731 SDNode *ChainNext = Queue.pop_back_val();
13732 if (!Visited.
insert(ChainNext).second)
13735 if (
MemSDNode *ChainLD = dyn_cast<MemSDNode>(ChainNext)) {
13739 if (!Visited.
count(ChainLD->getChain().getNode()))
13740 Queue.push_back(ChainLD->getChain().getNode());
13742 for (
const SDUse &O : ChainNext->
ops())
13743 if (!Visited.
count(O.getNode()))
13744 Queue.push_back(O.getNode());
13746 LoadRoots.
insert(ChainNext);
13757 for (
SDNode *
I : LoadRoots) {
13758 Queue.push_back(
I);
13760 while (!Queue.empty()) {
13761 SDNode *LoadRoot = Queue.pop_back_val();
13762 if (!Visited.
insert(LoadRoot).second)
13765 if (
MemSDNode *ChainLD = dyn_cast<MemSDNode>(LoadRoot))
13770 if (((isa<MemSDNode>(U) &&
13771 cast<MemSDNode>(U)->getChain().getNode() == LoadRoot) ||
13774 Queue.push_back(U);
13807 auto Final = Shifted;
13818 DAGCombinerInfo &DCI)
const {
13826 if (!DCI.isAfterLegalizeDAG())
13831 for (
const SDNode *U :
N->uses())
13836 auto OpSize =
N->getOperand(0).getValueSizeInBits();
13840 if (OpSize <
Size) {
13858 DAGCombinerInfo &DCI)
const {
13862 assert(Subtarget.useCRBits() &&
"Expecting to be tracking CR bits");
13873 N->getValueType(0) != MVT::i1)
13876 if (
N->getOperand(0).getValueType() != MVT::i32 &&
13877 N->getOperand(0).getValueType() != MVT::i64)
13885 cast<CondCodeSDNode>(
N->getOperand(
13887 unsigned OpBits =
N->getOperand(0).getValueSizeInBits();
13898 return (
N->getOpcode() ==
ISD::SETCC ? ConvertSETCCToSubtract(
N, DCI)
13921 if (
N->getOperand(0).getOpcode() !=
ISD::AND &&
13922 N->getOperand(0).getOpcode() !=
ISD::OR &&
13923 N->getOperand(0).getOpcode() !=
ISD::XOR &&
13933 N->getOperand(1).getOpcode() !=
ISD::AND &&
13934 N->getOperand(1).getOpcode() !=
ISD::OR &&
13935 N->getOperand(1).getOpcode() !=
ISD::XOR &&
13948 for (
unsigned i = 0; i < 2; ++i) {
13952 N->getOperand(i).getOperand(0).getValueType() == MVT::i1) ||
13953 isa<ConstantSDNode>(
N->getOperand(i)))
13964 while (!BinOps.
empty()) {
13972 for (
unsigned i = 0, ie = BinOp.
getNumOperands(); i != ie; ++i) {
14006 for (
unsigned i = 0, ie = Inputs.
size(); i != ie; ++i) {
14007 if (isa<ConstantSDNode>(Inputs[i]))
14030 for (
unsigned i = 0, ie = PromOps.
size(); i != ie; ++i) {
14052 for (
unsigned i = 0, ie = Inputs.
size(); i != ie; ++i) {
14055 if (isa<ConstantSDNode>(Inputs[i]))
14061 std::list<HandleSDNode> PromOpHandles;
14062 for (
auto &PromOp : PromOps)
14063 PromOpHandles.emplace_back(PromOp);
14070 while (!PromOpHandles.empty()) {
14072 PromOpHandles.pop_back();
14078 if (!isa<ConstantSDNode>(PromOp.
getOperand(0)) &&
14081 PromOpHandles.emplace_front(PromOp);
14086 if (isa<ConstantSDNode>(RepValue))
14095 default:
C = 0;
break;
14100 if ((!isa<ConstantSDNode>(PromOp.
getOperand(
C)) &&
14108 PromOpHandles.emplace_front(PromOp);
14116 for (
unsigned i = 0; i < 2; ++i)
14117 if (isa<ConstantSDNode>(Ops[
C+i]))
14126 return N->getOperand(0);
14134 DAGCombinerInfo &DCI)
const {
14152 if (
N->getValueType(0) != MVT::i32 &&
14153 N->getValueType(0) != MVT::i64)
14156 if (!((
N->getOperand(0).getValueType() == MVT::i1 && Subtarget.useCRBits()) ||
14157 (
N->getOperand(0).getValueType() == MVT::i32 && Subtarget.
isPPC64())))
14160 if (
N->getOperand(0).getOpcode() !=
ISD::AND &&
14161 N->getOperand(0).getOpcode() !=
ISD::OR &&
14162 N->getOperand(0).getOpcode() !=
ISD::XOR &&
14173 while (!BinOps.
empty()) {
14181 for (
unsigned i = 0, ie = BinOp.
getNumOperands(); i != ie; ++i) {
14212 for (
unsigned i = 0, ie = Inputs.
size(); i != ie; ++i) {
14213 if (isa<ConstantSDNode>(Inputs[i]))
14224 SelectTruncOp[0].
insert(std::make_pair(
User,
14228 SelectTruncOp[0].
insert(std::make_pair(
User,
14231 SelectTruncOp[1].
insert(std::make_pair(
User,
14237 for (
unsigned i = 0, ie = PromOps.
size(); i != ie; ++i) {
14246 SelectTruncOp[0].
insert(std::make_pair(
User,
14250 SelectTruncOp[0].
insert(std::make_pair(
User,
14253 SelectTruncOp[1].
insert(std::make_pair(
User,
14259 unsigned PromBits =
N->getOperand(0).getValueSizeInBits();
14260 bool ReallyNeedsExt =
false;
14264 for (
unsigned i = 0, ie = Inputs.
size(); i != ie; ++i) {
14265 if (isa<ConstantSDNode>(Inputs[i]))
14269 Inputs[i].getOperand(0).getValueSizeInBits();
14270 assert(PromBits < OpBits &&
"Truncation not to a smaller bit count?");
14275 OpBits-PromBits))) ||
14278 (OpBits-(PromBits-1)))) {
14279 ReallyNeedsExt =
true;
14287 for (
unsigned i = 0, ie = Inputs.
size(); i != ie; ++i) {
14291 if (isa<ConstantSDNode>(Inputs[i]))
14294 SDValue InSrc = Inputs[i].getOperand(0);
14308 std::list<HandleSDNode> PromOpHandles;
14309 for (
auto &PromOp : PromOps)
14310 PromOpHandles.emplace_back(PromOp);
14316 while (!PromOpHandles.empty()) {
14318 PromOpHandles.pop_back();
14322 default:
C = 0;
break;
14327 if ((!isa<ConstantSDNode>(PromOp.
getOperand(
C)) &&
14335 PromOpHandles.emplace_front(PromOp);
14345 (SelectTruncOp[1].count(PromOp.
getNode()) &&
14347 PromOpHandles.emplace_front(PromOp);
14356 for (
unsigned i = 0; i < 2; ++i) {
14357 if (!isa<ConstantSDNode>(Ops[
C+i]))
14374 auto SI0 = SelectTruncOp[0].
find(PromOp.
getNode());
14375 if (SI0 != SelectTruncOp[0].
end())
14377 auto SI1 = SelectTruncOp[1].
find(PromOp.
getNode());
14378 if (SI1 != SelectTruncOp[1].
end())
14387 if (!ReallyNeedsExt)
14388 return N->getOperand(0);
14395 N->getValueSizeInBits(0), PromBits),
14396 dl,
N->getValueType(0)));
14399 "Invalid extension type");
14402 DAG.
getConstant(
N->getValueSizeInBits(0) - PromBits, dl, ShiftAmountTy);
14410 DAGCombinerInfo &DCI)
const {
14412 "Should be called with a SETCC node");
14430 EVT VT =
N->getValueType(0);
14431 EVT OpVT =
LHS.getValueType();
14437 return DAGCombineTruncBoolExt(
N, DCI);
14442 if (
LoadSDNode *LD = dyn_cast<LoadSDNode>(
Op.getNode()))
14444 Op.getValueType() == MVT::f64;
14456combineElementTruncationToVectorTruncation(
SDNode *
N,
14457 DAGCombinerInfo &DCI)
const {
14459 "Should be called with a BUILD_VECTOR node");
14464 SDValue FirstInput =
N->getOperand(0);
14466 "The input operand must be an fp-to-int conversion.");
14475 bool IsSplat =
true;
14480 EVT TargetVT =
N->getValueType(0);
14481 for (
int i = 0, e =
N->getNumOperands(); i < e; ++i) {
14482 SDValue NextOp =
N->getOperand(i);
14486 if (NextConversion != FirstConversion)
14494 if (
N->getOperand(i) != FirstInput)
14505 for (
int i = 0, e =
N->getNumOperands(); i < e; ++i) {
14506 SDValue In =
N->getOperand(i).getOperand(0);
14529 EVT NewVT = TargetVT == MVT::v2i64 ? MVT::v2f64 : MVT::v4f32;
14531 return DAG.
getNode(Opcode, dl, TargetVT, BV);
14544 "Should be called with a BUILD_VECTOR node");
14549 if (!
N->getValueType(0).getVectorElementType().isByteSized())
14552 bool InputsAreConsecutiveLoads =
true;
14553 bool InputsAreReverseConsecutive =
true;
14554 unsigned ElemSize =
N->getValueType(0).getScalarType().getStoreSize();
14555 SDValue FirstInput =
N->getOperand(0);
14556 bool IsRoundOfExtLoad =
false;
14561 FirstLoad = cast<LoadSDNode>(FirstInput.
getOperand(0));
14566 N->getNumOperands() == 1)
14569 if (!IsRoundOfExtLoad)
14570 FirstLoad = cast<LoadSDNode>(FirstInput);
14574 for (
int i = 1, e =
N->getNumOperands(); i < e; ++i) {
14576 if (IsRoundOfExtLoad &&
N->getOperand(i).getOpcode() !=
ISD::FP_ROUND)
14579 SDValue NextInput = IsRoundOfExtLoad ?
N->getOperand(i).getOperand(0) :
14585 IsRoundOfExtLoad ?
N->getOperand(i-1).getOperand(0) :
N->getOperand(i-1);
14586 LoadSDNode *LD1 = cast<LoadSDNode>(PreviousInput);
14587 LoadSDNode *LD2 = cast<LoadSDNode>(NextInput);
14596 InputsAreConsecutiveLoads =
false;
14598 InputsAreReverseConsecutive =
false;
14601 if (!InputsAreConsecutiveLoads && !InputsAreReverseConsecutive)
14606 assert(!(InputsAreConsecutiveLoads && InputsAreReverseConsecutive) &&
14607 "The loads cannot be both consecutive and reverse consecutive.");
14611 if (InputsAreConsecutiveLoads) {
14612 assert(FirstLoad &&
"Input needs to be a LoadSDNode.");
14616 ReturnSDVal = WideLoad;
14617 }
else if (InputsAreReverseConsecutive) {
14619 assert(LastLoad &&
"Input needs to be a LoadSDNode.");
14624 for (
int i =
N->getNumOperands() - 1; i >= 0; i--)
14628 DAG.
getUNDEF(
N->getValueType(0)), Ops);
14632 for (
auto *LD : InputLoads)
14634 return ReturnSDVal;
14651 for (
unsigned i = 0; i <
N->getNumOperands(); i++) {
14653 ShuffleMask[CorrectElems & 0xF] = Elems & 0xF;
14655 ShuffleMask[(CorrectElems & 0xF0) >> 4] = (Elems & 0xF0) >> 4;
14656 CorrectElems = CorrectElems >> 8;
14657 Elems = Elems >> 8;
14664 EVT VT =
N->getValueType(0);
14702 auto isSExtOfVecExtract = [&](
SDValue Op) ->
bool {
14722 if (Input && Input != Extract.
getOperand(0))
14728 Elems = Elems << 8;
14737 for (
unsigned i = 0; i <
N->getNumOperands(); i++) {
14738 if (!isSExtOfVecExtract(
N->getOperand(i))) {
14745 int TgtElemArrayIdx;
14747 int OutputSize =
N->getValueType(0).getScalarSizeInBits();
14748 if (InputSize + OutputSize == 40)
14749 TgtElemArrayIdx = 0;
14750 else if (InputSize + OutputSize == 72)
14751 TgtElemArrayIdx = 1;
14752 else if (InputSize + OutputSize == 48)
14753 TgtElemArrayIdx = 2;
14754 else if (InputSize + OutputSize == 80)
14755 TgtElemArrayIdx = 3;
14756 else if (InputSize + OutputSize == 96)
14757 TgtElemArrayIdx = 4;
14761 uint64_t CorrectElems = TargetElems[TgtElemArrayIdx];
14763 ? CorrectElems & 0x0F0F0F0F0F0F0F0F
14764 : CorrectElems & 0xF0F0F0F0F0F0F0F0;
14765 if (Elems != CorrectElems) {
14781 if (
N->getValueType(0) != MVT::v1i128)
14784 SDValue Operand =
N->getOperand(0);
14790 auto *LD = cast<LoadSDNode>(Operand);
14791 EVT MemoryType = LD->getMemoryVT();
14795 bool ValidLDType = MemoryType == MVT::i8 || MemoryType == MVT::i16 ||
14796 MemoryType == MVT::i32 || MemoryType == MVT::i64;
14799 if (!ValidLDType ||
14805 LD->getChain(), LD->getBasePtr(),
14809 DAG.
getVTList(MVT::v1i128, MVT::Other),
14810 LoadOps, MemoryType, LD->getMemOperand());
14814 DAGCombinerInfo &DCI)
const {
14816 "Should be called with a BUILD_VECTOR node");
14821 if (!Subtarget.hasVSX())
14827 SDValue FirstInput =
N->getOperand(0);
14829 SDValue Reduced = combineElementTruncationToVectorTruncation(
N, DCI);
14844 if (Subtarget.hasP9Altivec() && !DCI.isBeforeLegalize()) {
14853 if (Subtarget.isISA3_1()) {
14859 if (
N->getValueType(0) != MVT::v2f64)
14870 if (FirstInput.
getOpcode() !=
N->getOperand(1).getOpcode())
14874 SDValue Ext2 =
N->getOperand(1).getOperand(0);
14881 if (!Ext1Op || !Ext2Op)
14890 if (FirstElem == 0 && SecondElem == 1)
14892 else if (FirstElem == 2 && SecondElem == 3)
14900 return DAG.
getNode(NodeType, dl, MVT::v2f64,
14905 DAGCombinerInfo &DCI)
const {
14908 "Need an int -> FP conversion node here");
14919 if (
Op.getValueType() != MVT::f32 &&
Op.getValueType() != MVT::f64)
14921 if (!
Op.getOperand(0).getValueType().isSimple())
14923 if (
Op.getOperand(0).getValueType().getSimpleVT() <=
MVT(MVT::i1) ||
14924 Op.getOperand(0).getValueType().getSimpleVT() >
MVT(MVT::i64))
14927 SDValue FirstOperand(
Op.getOperand(0));
14928 bool SubWordLoad = FirstOperand.getOpcode() ==
ISD::LOAD &&
14929 (FirstOperand.getValueType() == MVT::i8 ||
14930 FirstOperand.getValueType() == MVT::i16);
14931 if (Subtarget.hasP9Vector() && Subtarget.hasP9Altivec() && SubWordLoad) {
14933 bool DstDouble =
Op.getValueType() == MVT::f64;
14934 unsigned ConvOp =
Signed ?
14940 LoadSDNode *LDN = cast<LoadSDNode>(FirstOperand.getNode());
14948 SDValue ExtOps[] = { Ld, WidthConst };
14950 return DAG.
getNode(ConvOp, dl, DstDouble ? MVT::f64 : MVT::f32, Ext);
14952 return DAG.
getNode(ConvOp, dl, DstDouble ? MVT::f64 : MVT::f32, Ld);
14960 if (
Op.getOperand(0).getValueType() == MVT::i32)
14964 "UINT_TO_FP is supported only with FPCVT");
14968 unsigned FCFOp = (Subtarget.hasFPCVT() &&
Op.getValueType() == MVT::f32)
14973 MVT FCFTy = (Subtarget.hasFPCVT() &&
Op.getValueType() == MVT::f32)
14980 Subtarget.hasFPCVT()) ||
14982 SDValue Src =
Op.getOperand(0).getOperand(0);
14983 if (Src.getValueType() == MVT::f32) {
14985 DCI.AddToWorklist(Src.getNode());
14986 }
else if (Src.getValueType() != MVT::f64) {
14998 if (
Op.getValueType() == MVT::f32 && !Subtarget.hasFPCVT()) {
15001 DCI.AddToWorklist(
FP.getNode());
15025 switch (
N->getOpcode()) {
15030 Chain = LD->getChain();
15031 Base = LD->getBasePtr();
15032 MMO = LD->getMemOperand();
15051 MVT VecTy =
N->getValueType(0).getSimpleVT();
15059 Chain = Load.getValue(1);
15065 if (VecTy != MVT::v2f64) {
15092 switch (
N->getOpcode()) {
15097 Chain = ST->getChain();
15098 Base = ST->getBasePtr();
15099 MMO = ST->getMemOperand();
15119 SDValue Src =
N->getOperand(SrcOpnd);
15120 MVT VecTy = Src.getValueType().getSimpleVT();
15123 if (VecTy != MVT::v2f64) {
15129 DAG.
getVTList(MVT::v2f64, MVT::Other), Chain, Src);
15135 StoreOps, VecTy, MMO);
15142 DAGCombinerInfo &DCI)
const {
15145 unsigned Opcode =
N->getOperand(1).getOpcode();
15147 bool Strict =
N->getOperand(1)->isStrictFPOpcode();
15151 &&
"Not a FP_TO_INT Instruction!");
15153 SDValue Val =
N->getOperand(1).getOperand(Strict ? 1 : 0);
15154 EVT Op1VT =
N->getOperand(1).getValueType();
15157 if (!Subtarget.hasVSX() || !Subtarget.hasFPCVT() || !
isTypeLegal(ResVT))
15161 bool ValidTypeForStoreFltAsInt =
15162 (Op1VT == MVT::i32 || (Op1VT == MVT::i64 && Subtarget.
isPPC64()) ||
15163 (Subtarget.hasP9Vector() && (Op1VT == MVT::i16 || Op1VT == MVT::i8)));
15166 if (ResVT == MVT::ppcf128 || (ResVT == MVT::f128 && !Subtarget.hasP9Vector()))
15169 if ((Op1VT != MVT::i64 && !Subtarget.hasP8Vector()) ||
15170 cast<StoreSDNode>(
N)->isTruncatingStore() || !ValidTypeForStoreFltAsInt)
15177 SDValue Ops[] = {
N->getOperand(0), Val,
N->getOperand(2),
15183 cast<StoreSDNode>(
N)->getMemoryVT(),
15184 cast<StoreSDNode>(
N)->getMemOperand());
15192 bool PrevElemFromFirstVec = Mask[0] < NumElts;
15193 for (
int i = 1, e = Mask.size(); i < e; i++) {
15194 if (PrevElemFromFirstVec && Mask[i] < NumElts)
15196 if (!PrevElemFromFirstVec && Mask[i] >= NumElts)
15198 PrevElemFromFirstVec = !PrevElemFromFirstVec;
15210 FirstOp =
Op.getOperand(i);
15217 if (
Op.getOperand(i) != FirstOp && !
Op.getOperand(i).isUndef())
15227 Op =
Op.getOperand(0);
15242 int LHSMaxIdx,
int RHSMinIdx,
15243 int RHSMaxIdx,
int HalfVec,
15244 unsigned ValidLaneWidth,
15246 for (
int i = 0, e = ShuffV.
size(); i < e; i++) {
15247 int Idx = ShuffV[i];
15248 if ((
Idx >= 0 &&
Idx < LHSMaxIdx) || (
Idx >= RHSMinIdx &&
Idx < RHSMaxIdx))
15250 Subtarget.
isLittleEndian() ? HalfVec : HalfVec - ValidLaneWidth;
15261 SDLoc dl(OrigSToV);
15264 "Expecting a SCALAR_TO_VECTOR here");
15277 "Cannot produce a permuted scalar_to_vector for one element vector");
15279 unsigned ResultInElt = NumElts / 2;
15281 NewMask[ResultInElt] =
Idx->getZExtValue();
15306 int NumElts =
LHS.getValueType().getVectorNumElements();
15316 if (!Subtarget.hasDirectMove())
15326 Mask = cast<ShuffleVectorSDNode>(Res)->getMask();
15335 if (SToVLHS || SToVRHS) {
15342 if (SToVLHS && SToVRHS &&
15349 int NumEltsOut = ShuffV.
size();
15354 unsigned ValidLaneWidth =
15356 LHS.getValueType().getScalarSizeInBits()
15358 RHS.getValueType().getScalarSizeInBits();
15362 int LHSMaxIdx = -1;
15363 int RHSMinIdx = -1;
15364 int RHSMaxIdx = -1;
15365 int HalfVec =
LHS.getValueType().getVectorNumElements() / 2;
15377 LHSMaxIdx = NumEltsOut / NumEltsIn;
15386 RHSMinIdx = NumEltsOut;
15387 RHSMaxIdx = NumEltsOut / NumEltsIn + RHSMinIdx;
15400 HalfVec, ValidLaneWidth, Subtarget);
15405 if (!isa<ShuffleVectorSDNode>(Res))
15407 Mask = cast<ShuffleVectorSDNode>(Res)->getMask();
15426 if (IsLittleEndian) {
15429 if (Mask[0] < NumElts)
15430 for (
int i = 1, e =
Mask.size(); i < e; i += 2) {
15434 ShuffV[i] = (ShuffV[i - 1] >= 0 ? ShuffV[i - 1] : 0) + NumElts;
15439 for (
int i = 0, e =
Mask.size(); i <
e; i += 2) {
15443 ShuffV[i] = (ShuffV[i + 1] >= 0 ? ShuffV[i + 1] : 0) + NumElts;
15448 if (Mask[0] < NumElts)
15449 for (
int i = 0, e =
Mask.size(); i <
e; i += 2) {
15453 ShuffV[i] = ShuffV[i + 1] >= 0 ? ShuffV[i + 1] - NumElts : 0;
15458 for (
int i = 1, e =
Mask.size(); i <
e; i += 2) {
15462 ShuffV[i] = ShuffV[i - 1] >= 0 ? ShuffV[i - 1] - NumElts : 0;
15469 cast<BuildVectorSDNode>(TheSplat.
getNode())->getSplatValue();
15472 if (IsLittleEndian)
15481 DAGCombinerInfo &DCI)
const {
15483 "Not a reverse memop pattern!");
15488 auto I =
Mask.rbegin();
15489 auto E =
Mask.rend();
15491 for (;
I !=
E; ++
I) {
15508 if (!Subtarget.hasP9Vector())
15511 if(!IsElementReverse(SVN))
15550 if (IntrinsicID == Intrinsic::ppc_stdcx)
15552 else if (IntrinsicID == Intrinsic::ppc_stwcx)
15554 else if (IntrinsicID == Intrinsic::ppc_sthcx)
15556 else if (IntrinsicID == Intrinsic::ppc_stbcx)
15567 switch (
N->getOpcode()) {
15570 return combineADD(
N, DCI);
15579 !isa<ConstantSDNode>(Op2) ||
N->getValueType(0) != MVT::i64 ||
15589 if (!isUInt<32>(Imm))
15596 return combineSHL(
N, DCI);
15598 return combineSRA(
N, DCI);
15600 return combineSRL(
N, DCI);
15602 return combineMUL(
N, DCI);
15605 return combineFMALike(
N, DCI);
15608 return N->getOperand(0);
15612 return N->getOperand(0);
15618 return N->getOperand(0);
15624 return DAGCombineExtBoolTrunc(
N, DCI);
15626 return combineTRUNCATE(
N, DCI);
15628 if (
SDValue CSCC = combineSetCC(
N, DCI))
15632 return DAGCombineTruncBoolExt(
N, DCI);
15635 return combineFPToIntToFP(
N, DCI);
15638 LSBaseSDNode* LSBase = cast<LSBaseSDNode>(
N->getOperand(0));
15639 return combineVReverseMemOP(cast<ShuffleVectorSDNode>(
N), LSBase, DCI);
15641 return combineVectorShuffle(cast<ShuffleVectorSDNode>(
N), DCI.
DAG);
15644 EVT Op1VT =
N->getOperand(1).getValueType();
15645 unsigned Opcode =
N->getOperand(1).getOpcode();
15649 SDValue Val = combineStoreFPToInt(
N, DCI);
15656 SDValue Val= combineVReverseMemOP(SVN, cast<LSBaseSDNode>(
N), DCI);
15662 if (cast<StoreSDNode>(
N)->isUnindexed() && Opcode ==
ISD::BSWAP &&
15663 N->getOperand(1).getNode()->hasOneUse() &&
15664 (Op1VT == MVT::i32 || Op1VT == MVT::i16 ||
15665 (Subtarget.hasLDBRX() && Subtarget.
isPPC64() && Op1VT == MVT::i64))) {
15669 EVT mVT = cast<StoreSDNode>(
N)->getMemoryVT();
15673 SDValue BSwapOp =
N->getOperand(1).getOperand(0);
15680 if (Op1VT.
bitsGT(mVT)) {
15685 if (Op1VT == MVT::i64)
15690 N->getOperand(0), BSwapOp,
N->getOperand(2), DAG.
getValueType(mVT)
15694 Ops, cast<StoreSDNode>(
N)->getMemoryVT(),
15695 cast<StoreSDNode>(
N)->getMemOperand());
15701 isa<ConstantSDNode>(
N->getOperand(1)) && Op1VT == MVT::i32) {
15703 EVT MemVT = cast<StoreSDNode>(
N)->getMemoryVT();
15713 cast<StoreSDNode>(
N)->setTruncatingStore(
true);
15722 (StoreVT == MVT::v2f64 || StoreVT == MVT::v2i64 ||
15723 StoreVT == MVT::v4f32 || StoreVT == MVT::v4i32))
15730 EVT VT = LD->getValueType(0);
15737 (LoadVT == MVT::v2f64 || LoadVT == MVT::v2i64 ||
15738 LoadVT == MVT::v4f32 || LoadVT == MVT::v4i32))
15749 auto ReplaceTwoFloatLoad = [&]() {
15750 if (VT != MVT::i64)
15765 if (!LD->hasNUsesOfValue(2, 0))
15768 auto UI = LD->use_begin();
15769 while (UI.getUse().getResNo() != 0) ++UI;
15771 while (UI.getUse().getResNo() != 0) ++UI;
15772 SDNode *RightShift = *UI;
15780 if (RightShift->getOpcode() !=
ISD::SRL ||
15781 !isa<ConstantSDNode>(RightShift->getOperand(1)) ||
15782 RightShift->getConstantOperandVal(1) != 32 ||
15783 !RightShift->hasOneUse())
15786 SDNode *Trunc2 = *RightShift->use_begin();
15796 Bitcast->getValueType(0) != MVT::f32)
15808 SDValue BasePtr = LD->getBasePtr();
15809 if (LD->isIndexed()) {
15811 "Non-pre-inc AM on PPC?");
15819 SDValue FloatLoad = DAG.
getLoad(MVT::f32, dl, LD->getChain(), BasePtr,
15820 LD->getPointerInfo(), LD->getAlign(),
15821 MMOFlags, LD->getAAInfo());
15827 LD->getPointerInfo().getWithOffset(4),
15830 if (LD->isIndexed()) {
15844 if (ReplaceTwoFloatLoad())
15847 EVT MemVT = LD->getMemoryVT();
15850 if (LD->isUnindexed() && VT.
isVector() &&
15853 !Subtarget.hasP8Vector() &&
15854 (VT == MVT::v16i8 || VT == MVT::v8i16 || VT == MVT::v4i32 ||
15855 VT == MVT::v4f32))) &&
15856 LD->getAlign() < ABIAlignment) {
15858 SDValue Chain = LD->getChain();
15887 MVT PermCntlTy, PermTy, LDTy;
15888 Intr = isLittleEndian ? Intrinsic::ppc_altivec_lvsr
15889 : Intrinsic::ppc_altivec_lvsl;
15890 IntrLD = Intrinsic::ppc_altivec_lvx;
15891 IntrPerm = Intrinsic::ppc_altivec_vperm;
15892 PermCntlTy = MVT::v16i8;
15893 PermTy = MVT::v4i32;
15912 SDValue BaseLoadOps[] = { Chain, LDXIntID,
Ptr };
15916 BaseLoadOps, LDTy, BaseMMO);
15925 int IncValue = IncOffset;
15942 SDValue ExtraLoadOps[] = { Chain, LDXIntID,
Ptr };
15946 ExtraLoadOps, LDTy, ExtraMMO);
15957 if (isLittleEndian)
15959 ExtraLoad, BaseLoad, PermCntl, DAG, dl);
15962 BaseLoad, ExtraLoad, PermCntl, DAG, dl);
15965 Perm = Subtarget.hasAltivec()
15981 unsigned IID =
N->getConstantOperandVal(0);
15983 : Intrinsic::ppc_altivec_lvsl);
15984 if (IID ==
Intr &&
N->getOperand(1)->getOpcode() ==
ISD::ADD) {
15991 .
zext(
Add.getScalarValueSizeInBits()))) {
15992 SDNode *BasePtr =
Add->getOperand(0).getNode();
15993 for (
SDNode *U : BasePtr->uses()) {
15995 U->getConstantOperandVal(0) == IID) {
16005 if (isa<ConstantSDNode>(
Add->getOperand(1))) {
16006 SDNode *BasePtr =
Add->getOperand(0).getNode();
16007 for (
SDNode *U : BasePtr->uses()) {
16009 isa<ConstantSDNode>(U->getOperand(1)) &&
16010 (
Add->getConstantOperandVal(1) - U->getConstantOperandVal(1)) %
16016 V->getConstantOperandVal(0) == IID) {
16028 (IID == Intrinsic::ppc_altivec_vmaxsw ||
16029 IID == Intrinsic::ppc_altivec_vmaxsh ||
16030 IID == Intrinsic::ppc_altivec_vmaxsb)) {
16046 V2.getOperand(1) == V1) {
16061 switch (
N->getConstantOperandVal(1)) {
16064 case Intrinsic::ppc_altivec_vsum4sbs:
16065 case Intrinsic::ppc_altivec_vsum4shs:
16066 case Intrinsic::ppc_altivec_vsum4ubs: {
16072 dyn_cast<BuildVectorSDNode>(
N->getOperand(3))) {
16073 APInt APSplatBits, APSplatUndef;
16074 unsigned SplatBitSize;
16077 APSplatBits, APSplatUndef, SplatBitSize, HasAnyUndefs, 0,
16080 if (BVNIsConstantSplat && APSplatBits == 0)
16085 case Intrinsic::ppc_vsx_lxvw4x:
16086 case Intrinsic::ppc_vsx_lxvd2x:
16098 switch (
N->getConstantOperandVal(1)) {
16101 case Intrinsic::ppc_vsx_stxvw4x:
16102 case Intrinsic::ppc_vsx_stxvd2x:
16111 bool Is64BitBswapOn64BitTgt =
16112 Subtarget.
isPPC64() &&
N->getValueType(0) == MVT::i64;
16114 N->getOperand(0).hasOneUse();
16115 if (IsSingleUseNormalLd &&
16116 (
N->getValueType(0) == MVT::i32 ||
N->getValueType(0) == MVT::i16 ||
16117 (Subtarget.hasLDBRX() && Is64BitBswapOn64BitTgt))) {
16128 DAG.
getVTList(
N->getValueType(0) == MVT::i64 ?
16129 MVT::i64 : MVT::i32, MVT::Other),
16130 Ops, LD->getMemoryVT(), LD->getMemOperand());
16134 if (
N->getValueType(0) == MVT::i16)
16151 !IsSingleUseNormalLd)
16153 LoadSDNode *LD = cast<LoadSDNode>(
N->getOperand(0));
16156 if (!LD->isSimple())
16158 SDValue BasePtr = LD->getBasePtr();
16160 LD->getPointerInfo(), LD->getAlign());
16165 LD->getMemOperand(), 4, 4);
16175 Hi.getOperand(0).getValue(1),
Lo.getOperand(0).getValue(1));
16184 if (!
N->getOperand(0).hasOneUse() &&
16185 !
N->getOperand(1).hasOneUse() &&
16186 !
N->getOperand(2).hasOneUse()) {
16189 SDNode *VCMPrecNode =
nullptr;
16191 SDNode *LHSN =
N->getOperand(0).getNode();
16195 UI->getOperand(1) ==
N->getOperand(1) &&
16196 UI->getOperand(2) ==
N->getOperand(2) &&
16197 UI->getOperand(0) ==
N->getOperand(0)) {
16210 SDNode *FlagUser =
nullptr;
16212 FlagUser ==
nullptr; ++UI) {
16213 assert(UI != VCMPrecNode->
use_end() &&
"Didn't find user!");
16226 return SDValue(VCMPrecNode, 0);
16248 auto RHSAPInt =
RHS->getAsAPIntVal();
16249 if (!RHSAPInt.isIntN(64))
16252 unsigned Val = RHSAPInt.getZExtValue();
16253 auto isImpossibleCompare = [&]() {
16256 if (Val != 0 && Val != 1) {
16258 return N->getOperand(0);
16261 N->getOperand(0),
N->getOperand(4));
16266 unsigned StoreWidth = 0;
16269 if (
SDValue Impossible = isImpossibleCompare())
16283 auto *MemNode = cast<MemSDNode>(
LHS);
16286 DAG.
getVTList(MVT::i32, MVT::Other, MVT::Glue), Ops,
16287 MemNode->getMemoryVT(), MemNode->getMemOperand());
16291 if (
N->getOperand(0) ==
LHS.getValue(1))
16292 InChain =
LHS.getOperand(0);
16304 DAG.
getRegister(PPC::CR0, MVT::i32),
N->getOperand(4),
16310 assert(isDot &&
"Can't compare against a vector result!");
16312 if (
SDValue Impossible = isImpossibleCompare())
16315 bool BranchOnWhenPredTrue = (
CC ==
ISD::SETEQ) ^ (Val == 0);
16322 EVT VTs[] = {
LHS.getOperand(2).getValueType(), MVT::Glue };
16327 switch (
LHS.getConstantOperandVal(1)) {
16346 N->getOperand(4), CompNode.
getValue(1));
16351 return DAGCombineBuildVector(
N, DCI);
16362 EVT VT =
N->getValueType(0);
16363 if (VT == MVT::i64 && !Subtarget.
isPPC64())
16365 if ((VT != MVT::i32 && VT != MVT::i64) ||
16373 unsigned Lg2 = (IsNegPow2 ? -Divisor : Divisor).
countr_zero();
16393 const APInt &DemandedElts,
16395 unsigned Depth)
const {
16397 switch (
Op.getOpcode()) {
16401 if (cast<VTSDNode>(
Op.getOperand(2))->getVT() == MVT::i16)
16402 Known.
Zero = 0xFFFF0000;
16406 switch (
Op.getConstantOperandVal(0)) {
16408 case Intrinsic::ppc_altivec_vcmpbfp_p:
16409 case Intrinsic::ppc_altivec_vcmpeqfp_p:
16410 case Intrinsic::ppc_altivec_vcmpequb_p:
16411 case Intrinsic::ppc_altivec_vcmpequh_p:
16412 case Intrinsic::ppc_altivec_vcmpequw_p:
16413 case Intrinsic::ppc_altivec_vcmpequd_p:
16414 case Intrinsic::ppc_altivec_vcmpequq_p:
16415 case Intrinsic::ppc_altivec_vcmpgefp_p:
16416 case Intrinsic::ppc_altivec_vcmpgtfp_p:
16417 case Intrinsic::ppc_altivec_vcmpgtsb_p:
16418 case Intrinsic::ppc_altivec_vcmpgtsh_p:
16419 case Intrinsic::ppc_altivec_vcmpgtsw_p:
16420 case Intrinsic::ppc_altivec_vcmpgtsd_p:
16421 case Intrinsic::ppc_altivec_vcmpgtsq_p:
16422 case Intrinsic::ppc_altivec_vcmpgtub_p:
16423 case Intrinsic::ppc_altivec_vcmpgtuh_p:
16424 case Intrinsic::ppc_altivec_vcmpgtuw_p:
16425 case Intrinsic::ppc_altivec_vcmpgtud_p:
16426 case Intrinsic::ppc_altivec_vcmpgtuq_p:
16433 switch (
Op.getConstantOperandVal(1)) {
16436 case Intrinsic::ppc_load2r:
16438 Known.
Zero = 0xFFFF0000;
16468 if (
ML->getLoopDepth() > 1 &&
ML->getSubLoops().empty())
16477 for (
auto I =
ML->block_begin(), IE =
ML->block_end();
I != IE; ++
I)
16479 LoopSize +=
TII->getInstSizeInBytes(J);
16484 if (LoopSize > 16 && LoopSize <= 32)
16498 if (Constraint.
size() == 1) {
16499 switch (Constraint[0]) {
16517 }
else if (Constraint ==
"wc") {
16519 }
else if (Constraint ==
"wa" || Constraint ==
"wd" ||
16520 Constraint ==
"wf" || Constraint ==
"ws" ||
16521 Constraint ==
"wi" || Constraint ==
"ww") {
16534 Value *CallOperandVal =
info.CallOperandVal;
16537 if (!CallOperandVal)
16544 else if ((
StringRef(constraint) ==
"wa" ||
16556 switch (*constraint) {
16586std::pair<unsigned, const TargetRegisterClass *>
16590 if (Constraint.
size() == 1) {
16592 switch (Constraint[0]) {
16594 if (VT == MVT::i64 && Subtarget.
isPPC64())
16595 return std::make_pair(0U, &PPC::G8RC_NOX0RegClass);
16596 return std::make_pair(0U, &PPC::GPRC_NOR0RegClass);
16598 if (VT == MVT::i64 && Subtarget.
isPPC64())
16599 return std::make_pair(0U, &PPC::G8RCRegClass);
16600 return std::make_pair(0U, &PPC::GPRCRegClass);
16606 if (Subtarget.hasSPE()) {
16607 if (VT == MVT::f32 || VT == MVT::i32)
16608 return std::make_pair(0U, &PPC::GPRCRegClass);
16609 if (VT == MVT::f64 || VT == MVT::i64)
16610 return std::make_pair(0U, &PPC::SPERCRegClass);
16612 if (VT == MVT::f32 || VT == MVT::i32)
16613 return std::make_pair(0U, &PPC::F4RCRegClass);
16614 if (VT == MVT::f64 || VT == MVT::i64)
16615 return std::make_pair(0U, &PPC::F8RCRegClass);
16619 if (Subtarget.hasAltivec() && VT.
isVector())
16620 return std::make_pair(0U, &PPC::VRRCRegClass);
16621 else if (Subtarget.hasVSX())
16623 return std::make_pair(0U, &PPC::VFRCRegClass);
16626 return std::make_pair(0U, &PPC::CRRCRegClass);
16628 }
else if (Constraint ==
"wc" && Subtarget.useCRBits()) {
16630 return std::make_pair(0U, &PPC::CRBITRCRegClass);
16631 }
else if ((Constraint ==
"wa" || Constraint ==
"wd" ||
16632 Constraint ==
"wf" || Constraint ==
"wi") &&
16633 Subtarget.hasVSX()) {
16637 return std::make_pair(0U, &PPC::VSRCRegClass);
16638 if (VT == MVT::f32 && Subtarget.hasP8Vector())
16639 return std::make_pair(0U, &PPC::VSSRCRegClass);
16640 return std::make_pair(0U, &PPC::VSFRCRegClass);
16641 }
else if ((Constraint ==
"ws" || Constraint ==
"ww") && Subtarget.hasVSX()) {
16642 if (VT == MVT::f32 && Subtarget.hasP8Vector())
16643 return std::make_pair(0U, &PPC::VSSRCRegClass);
16645 return std::make_pair(0U, &PPC::VSFRCRegClass);
16646 }
else if (Constraint ==
"lr") {
16647 if (VT == MVT::i64)
16648 return std::make_pair(0U, &PPC::LR8RCRegClass);
16650 return std::make_pair(0U, &PPC::LRRCRegClass);
16655 if (Constraint[0] ==
'{' && Constraint[Constraint.
size() - 1] ==
'}') {
16659 if (Constraint.
size() > 3 && Constraint[1] ==
'v' && Constraint[2] ==
's') {
16660 int VSNum = atoi(Constraint.
data() + 3);
16661 assert(VSNum >= 0 && VSNum <= 63 &&
16662 "Attempted to access a vsr out of range");
16664 return std::make_pair(PPC::VSL0 + VSNum, &PPC::VSRCRegClass);
16665 return std::make_pair(PPC::V0 + VSNum - 32, &PPC::VSRCRegClass);
16670 if (Constraint.
size() > 3 && Constraint[1] ==
'f') {
16671 int RegNum = atoi(Constraint.
data() + 2);
16672 if (RegNum > 31 || RegNum < 0)
16674 if (VT == MVT::f32 || VT == MVT::i32)
16675 return Subtarget.hasSPE()
16676 ? std::make_pair(PPC::R0 + RegNum, &PPC::GPRCRegClass)
16677 : std::make_pair(PPC::F0 + RegNum, &PPC::F4RCRegClass);
16678 if (VT == MVT::f64 || VT == MVT::i64)
16679 return Subtarget.hasSPE()
16680 ? std::make_pair(PPC::S0 + RegNum, &PPC::SPERCRegClass)
16681 : std::make_pair(PPC::F0 + RegNum, &PPC::F8RCRegClass);
16685 std::pair<unsigned, const TargetRegisterClass *> R =
16694 if (R.first && VT == MVT::i64 && Subtarget.
isPPC64() &&
16695 PPC::GPRCRegClass.contains(R.first))
16696 return std::make_pair(
TRI->getMatchingSuperReg(R.first,
16697 PPC::sub_32, &PPC::G8RCRegClass),
16698 &PPC::G8RCRegClass);
16701 if (!R.second &&
StringRef(
"{cc}").equals_insensitive(Constraint)) {
16702 R.first = PPC::CR0;
16703 R.second = &PPC::CRRCRegClass;
16707 if (Subtarget.
isAIXABI() && !
TM.getAIXExtendedAltivecABI()) {
16708 if (((R.first >= PPC::V20 && R.first <= PPC::V31) ||
16709 (R.first >= PPC::VF20 && R.first <= PPC::VF31)) &&
16710 (R.second == &PPC::VSRCRegClass || R.second == &PPC::VSFRCRegClass))
16711 errs() <<
"warning: vector registers 20 to 32 are reserved in the "
16712 "default AIX AltiVec ABI and cannot be used\n";
16722 std::vector<SDValue> &Ops,
16727 if (Constraint.
size() > 1)
16730 char Letter = Constraint[0];
16745 EVT TCVT = MVT::i64;
16750 if (isInt<16>(
Value))
16754 if (isShiftedUInt<16, 16>(
Value))
16758 if (isShiftedInt<16, 16>(
Value))
16762 if (isUInt<16>(
Value))
16778 if (isInt<16>(-
Value))
16786 if (Result.getNode()) {
16787 Ops.push_back(Result);
16798 if (
I.getNumOperands() <= 1)
16800 if (!isa<ConstantSDNode>(Ops[1].getNode()))
16802 auto IntrinsicID = Ops[1].getNode()->getAsZExtVal();
16803 if (IntrinsicID != Intrinsic::ppc_tdw && IntrinsicID != Intrinsic::ppc_tw &&
16804 IntrinsicID != Intrinsic::ppc_trapd && IntrinsicID != Intrinsic::ppc_trap)
16807 if (
I.hasMetadata(
"annotation")) {
16808 MDNode *MDN =
I.getMetadata(
"annotation");
16837 switch (AM.
Scale) {
16868 unsigned Depth =
Op.getConstantOperandVal(0);
16874 bool isPPC64 = Subtarget.
isPPC64();
16886 isPPC64 ? MVT::i64 : MVT::i32);
16893 SDValue RetAddrFI = getReturnAddrFrameIndex(DAG);
16901 unsigned Depth =
Op.getConstantOperandVal(0);
16908 bool isPPC64 = PtrVT == MVT::i64;
16914 FrameReg = isPPC64 ? PPC::X1 : PPC::R1;
16916 FrameReg = isPPC64 ? PPC::FP8 : PPC::FP;
16930 bool isPPC64 = Subtarget.
isPPC64();
16964 if (isa<JumpTableSDNode>(GA) || isa<BlockAddressSDNode>(GA))
16982 unsigned Intrinsic)
const {
16983 switch (Intrinsic) {
16984 case Intrinsic::ppc_atomicrmw_xchg_i128:
16985 case Intrinsic::ppc_atomicrmw_add_i128:
16986 case Intrinsic::ppc_atomicrmw_sub_i128:
16987 case Intrinsic::ppc_atomicrmw_nand_i128:
16988 case Intrinsic::ppc_atomicrmw_and_i128:
16989 case Intrinsic::ppc_atomicrmw_or_i128:
16990 case Intrinsic::ppc_atomicrmw_xor_i128:
16991 case Intrinsic::ppc_cmpxchg_i128:
16993 Info.memVT = MVT::i128;
16994 Info.ptrVal =
I.getArgOperand(0);
17000 case Intrinsic::ppc_atomic_load_i128:
17002 Info.memVT = MVT::i128;
17003 Info.ptrVal =
I.getArgOperand(0);
17008 case Intrinsic::ppc_atomic_store_i128:
17010 Info.memVT = MVT::i128;
17011 Info.ptrVal =
I.getArgOperand(2);
17016 case Intrinsic::ppc_altivec_lvx:
17017 case Intrinsic::ppc_altivec_lvxl:
17018 case Intrinsic::ppc_altivec_lvebx:
17019 case Intrinsic::ppc_altivec_lvehx:
17020 case Intrinsic::ppc_altivec_lvewx:
17021 case Intrinsic::ppc_vsx_lxvd2x:
17022 case Intrinsic::ppc_vsx_lxvw4x:
17023 case Intrinsic::ppc_vsx_lxvd2x_be:
17024 case Intrinsic::ppc_vsx_lxvw4x_be:
17025 case Intrinsic::ppc_vsx_lxvl:
17026 case Intrinsic::ppc_vsx_lxvll: {
17028 switch (Intrinsic) {
17029 case Intrinsic::ppc_altivec_lvebx:
17032 case Intrinsic::ppc_altivec_lvehx:
17035 case Intrinsic::ppc_altivec_lvewx:
17038 case Intrinsic::ppc_vsx_lxvd2x:
17039 case Intrinsic::ppc_vsx_lxvd2x_be:
17049 Info.ptrVal =
I.getArgOperand(0);
17056 case Intrinsic::ppc_altivec_stvx:
17057 case Intrinsic::ppc_altivec_stvxl:
17058 case Intrinsic::ppc_altivec_stvebx:
17059 case Intrinsic::ppc_altivec_stvehx:
17060 case Intrinsic::ppc_altivec_stvewx:
17061 case Intrinsic::ppc_vsx_stxvd2x:
17062 case Intrinsic::ppc_vsx_stxvw4x:
17063 case Intrinsic::ppc_vsx_stxvd2x_be:
17064 case Intrinsic::ppc_vsx_stxvw4x_be:
17065 case Intrinsic::ppc_vsx_stxvl:
17066 case Intrinsic::ppc_vsx_stxvll: {
17068 switch (Intrinsic) {
17069 case Intrinsic::ppc_altivec_stvebx:
17072 case Intrinsic::ppc_altivec_stvehx:
17075 case Intrinsic::ppc_altivec_stvewx:
17078 case Intrinsic::ppc_vsx_stxvd2x:
17079 case Intrinsic::ppc_vsx_stxvd2x_be:
17089 Info.ptrVal =
I.getArgOperand(1);
17096 case Intrinsic::ppc_stdcx:
17097 case Intrinsic::ppc_stwcx:
17098 case Intrinsic::ppc_sthcx:
17099 case Intrinsic::ppc_stbcx: {
17101 auto Alignment =
Align(8);
17102 switch (Intrinsic) {
17103 case Intrinsic::ppc_stdcx:
17106 case Intrinsic::ppc_stwcx:
17108 Alignment =
Align(4);
17110 case Intrinsic::ppc_sthcx:
17112 Alignment =
Align(2);
17114 case Intrinsic::ppc_stbcx:
17116 Alignment =
Align(1);
17121 Info.ptrVal =
I.getArgOperand(0);
17123 Info.align = Alignment;
17141 if (Subtarget.hasAltivec() &&
Op.size() >= 16) {
17142 if (
Op.isMemset() && Subtarget.hasVSX()) {
17147 if (TailSize > 2 && TailSize <= 4) {
17152 if (
Op.isAligned(
Align(16)) || Subtarget.hasP8Vector())
17171 return !(BitSize == 0 || BitSize > 64);
17179 return NumBits1 == 64 && NumBits2 == 32;
17187 return NumBits1 == 64 && NumBits2 == 32;
17193 if (
LoadSDNode *LD = dyn_cast<LoadSDNode>(Val)) {
17194 EVT MemVT = LD->getMemoryVT();
17195 if ((MemVT == MVT::i1 || MemVT == MVT::i8 || MemVT == MVT::i16 ||
17196 (Subtarget.
isPPC64() && MemVT == MVT::i32)) &&
17212 "invalid fpext types");
17214 if (DestVT == MVT::f128)
17220 return isInt<16>(Imm) || isUInt<16>(Imm);
17224 return isInt<16>(Imm) || isUInt<16>(Imm);
17229 unsigned *
Fast)
const {
17243 !Subtarget.allowsUnalignedFPAccess())
17247 if (Subtarget.hasVSX()) {
17248 if (VT != MVT::v2f64 && VT != MVT::v2i64 &&
17249 VT != MVT::v4f32 && VT != MVT::v4i32)
17256 if (VT == MVT::ppcf128)
17270 if (
auto *ConstNode = dyn_cast<ConstantSDNode>(
C.getNode())) {
17271 if (!ConstNode->getAPIntValue().isSignedIntN(64))
17279 int64_t Imm = ConstNode->getSExtValue();
17280 unsigned Shift = llvm::countr_zero<uint64_t>(Imm);
17282 if (isInt<16>(Imm))
17307 return Subtarget.hasP9Vector();
17315 if (!
I->hasOneUse())
17319 assert(
User &&
"A single use instruction with no uses.");
17321 switch (
I->getOpcode()) {
17322 case Instruction::FMul: {
17324 if (
User->getOpcode() != Instruction::FSub &&
17325 User->getOpcode() != Instruction::FAdd)
17338 case Instruction::Load: {
17351 if (
User->getOpcode() != Instruction::Store)
17371 static const MCPhysReg ScratchRegs[] = {
17372 PPC::X12, PPC::LR8, PPC::CTR8, 0
17375 return ScratchRegs;
17379 const Constant *PersonalityFn)
const {
17380 return Subtarget.
isPPC64() ? PPC::X3 : PPC::R3;
17384 const Constant *PersonalityFn)
const {
17385 return Subtarget.
isPPC64() ? PPC::X4 : PPC::R4;
17390 EVT VT ,
unsigned DefinedValues)
const {
17391 if (VT == MVT::v2i64)
17392 return Subtarget.hasDirectMove();
17394 if (Subtarget.hasVSX())
17428 bool LegalOps,
bool OptForSize,
17430 unsigned Depth)
const {
17434 unsigned Opc =
Op.getOpcode();
17435 EVT VT =
Op.getValueType();
17460 if (Flags.hasNoSignedZeros() ||
Options.NoSignedZerosFPMath) {
17464 N0Cost,
Depth + 1);
17468 N1Cost,
Depth + 1);
17470 if (NegN0 && N0Cost <= N1Cost) {
17471 Cost = std::min(N0Cost, N2Cost);
17472 return DAG.
getNode(Opc, Loc, VT, NegN0, N1, NegN2, Flags);
17473 }
else if (NegN1) {
17474 Cost = std::min(N1Cost, N2Cost);
17475 return DAG.
getNode(Opc, Loc, VT, N0, NegN1, NegN2, Flags);
17518 bool ForCodeSize)
const {
17519 if (!VT.
isSimple() || !Subtarget.hasVSX())
17529 if (Subtarget.hasPrefixInstrs()) {
17534 APSInt IntResult(16,
false);
17539 if (IsExact && IntResult <= 15 && IntResult >= -16)
17541 return Imm.isZero();
17544 return Imm.isPosZero();
17556 unsigned Opcode =
N->getOpcode();
17557 unsigned TargetOpcode;
17576 if (Mask->getZExtValue() == OpSizeInBits - 1)
17582SDValue PPCTargetLowering::combineSHL(
SDNode *
N, DAGCombinerInfo &DCI)
const {
17588 if (!Subtarget.isISA3_0() || !Subtarget.
isPPC64() ||
17591 N->getValueType(0) != MVT::i64)
17606 ShiftBy = DCI.DAG.getConstant(CN1->
getZExtValue(),
DL, MVT::i32);
17612SDValue PPCTargetLowering::combineSRA(
SDNode *
N, DAGCombinerInfo &DCI)
const {
17619SDValue PPCTargetLowering::combineSRL(
SDNode *
N, DAGCombinerInfo &DCI)
const {
17638 auto isZextOfCompareWithConstant = [](
SDValue Op) {
17640 Op.getValueType() != MVT::i64)
17644 if (Cmp.getOpcode() !=
ISD::SETCC || !Cmp.hasOneUse() ||
17645 Cmp.getOperand(0).getValueType() != MVT::i64)
17648 if (
auto *
Constant = dyn_cast<ConstantSDNode>(Cmp.getOperand(1))) {
17649 int64_t NegConstant = 0 -
Constant->getSExtValue();
17652 return isInt<16>(NegConstant);
17658 bool LHSHasPattern = isZextOfCompareWithConstant(
LHS);
17659 bool RHSHasPattern = isZextOfCompareWithConstant(
RHS);
17662 if (LHSHasPattern && !RHSHasPattern)
17664 else if (!LHSHasPattern && !RHSHasPattern)
17670 SDValue Z = Cmp.getOperand(0);
17671 auto *
Constant = cast<ConstantSDNode>(Cmp.getOperand(1));
17672 int64_t NegConstant = 0 -
Constant->getSExtValue();
17674 switch(cast<CondCodeSDNode>(Cmp.getOperand(2))->get()) {
17685 SDValue AddOrZ = NegConstant != 0 ?
Add : Z;
17700 SDValue AddOrZ = NegConstant != 0 ?
Add : Z;
17737 if (!GSDN || !ConstNode)
17744 if (!isInt<34>(NewOffset))
17757SDValue PPCTargetLowering::combineADD(
SDNode *
N, DAGCombinerInfo &DCI)
const {
17777 DAGCombinerInfo &DCI)
const {
17779 if (Subtarget.useCRBits()) {
17781 if (
SDValue CRTruncValue = DAGCombineTruncBoolExt(
N, DCI))
17782 return CRTruncValue;
17789 if (Op0.
getValueType() != MVT::i128 ||
N->getValueType(0) != MVT::i64)
17792 int EltToExtract = DCI.DAG.getDataLayout().isBigEndian() ? 1 : 0;
17802 EltToExtract = EltToExtract ? 0 : 1;
17812 return DCI.DAG.getNode(
17814 DCI.DAG.getTargetConstant(EltToExtract, dl, MVT::i32));
17819SDValue PPCTargetLowering::combineMUL(
SDNode *
N, DAGCombinerInfo &DCI)
const {
17823 if (!ConstOpOrElement)
17831 auto IsProfitable = [
this](
bool IsNeg,
bool IsAddOne,
EVT VT) ->
bool {
17854 return IsAddOne && IsNeg ? VT.
isVector() :
true;
17858 EVT VT =
N->getValueType(0);
17865 if ((MulAmtAbs - 1).isPowerOf2()) {
17869 if (!IsProfitable(IsNeg,
true, VT))
17882 }
else if ((MulAmtAbs + 1).isPowerOf2()) {
17886 if (!IsProfitable(IsNeg,
false, VT))
17907 DAGCombinerInfo &DCI)
const {
17912 EVT VT =
N->getValueType(0);
17915 unsigned Opc =
N->getOpcode();
17917 bool LegalOps = !DCI.isBeforeLegalizeOps();
17925 if (!
Flags.hasNoSignedZeros() && !
Options.NoSignedZerosFPMath)
17941bool PPCTargetLowering::mayBeEmittedAsTailCall(
const CallInst *CI)
const {
17958 if (!Callee ||
Callee->isVarArg())
17971bool PPCTargetLowering::
17972isMaskAndCmp0FoldingBeneficial(
const Instruction &AndI)
const {
17975 if (
const ConstantInt *CI = dyn_cast<ConstantInt>(Mask)) {
17977 if (CI->getBitWidth() > 64)
17979 int64_t ConstVal = CI->getZExtValue();
17980 return isUInt<16>(ConstVal) ||
17981 (isUInt<16>(ConstVal >> 16) && !(ConstVal & 0xFFFF));
17990PPC::AddrMode PPCTargetLowering::getAddrModeForFlags(
unsigned Flags)
const {
17996 if ((Flags & FlagSet) == FlagSet)
17999 if ((Flags & FlagSet) == FlagSet)
18002 if ((Flags & FlagSet) == FlagSet)
18005 if ((Flags & FlagSet) == FlagSet)
18026 if ((FrameIndexAlign % 4) != 0)
18027 FlagSet &= ~PPC::MOF_RPlusSImm16Mult4;
18028 if ((FrameIndexAlign % 16) != 0)
18029 FlagSet &= ~PPC::MOF_RPlusSImm16Mult16;
18033 if ((FrameIndexAlign % 4) == 0)
18035 if ((FrameIndexAlign % 16) == 0)
18048 auto SetAlignFlagsForImm = [&](
uint64_t Imm) {
18049 if ((Imm & 0x3) == 0)
18051 if ((Imm & 0xf) == 0)
18057 const APInt &ConstImm = CN->getAPIntValue();
18076 const APInt &ConstImm = CN->getAPIntValue();
18086 }
else if (
RHS.getOpcode() ==
PPCISD::Lo && !
RHS.getConstantOperandVal(1))
18098 isValidPCRelNode<ConstantPoolSDNode>(
N) ||
18099 isValidPCRelNode<GlobalAddressSDNode>(
N) ||
18100 isValidPCRelNode<JumpTableSDNode>(
N) ||
18101 isValidPCRelNode<BlockAddressSDNode>(
N));
18106unsigned PPCTargetLowering::computeMOFlags(
const SDNode *Parent,
SDValue N,
18111 if (!Subtarget.hasP9Vector())
18115 if (Subtarget.hasPrefixInstrs())
18118 if (Subtarget.hasSPE())
18127 unsigned ParentOp = Parent->
getOpcode();
18131 if ((
ID == Intrinsic::ppc_vsx_lxvp) || (
ID == Intrinsic::ppc_vsx_stxvp)) {
18132 SDValue IntrinOp = (
ID == Intrinsic::ppc_vsx_lxvp)
18143 if (
const LSBaseSDNode *LSB = dyn_cast<LSBaseSDNode>(Parent))
18144 if (LSB->isIndexed())
18149 const MemSDNode *MN = dyn_cast<MemSDNode>(Parent);
18150 assert(MN &&
"Parent should be a MemSDNode!");
18155 "Not expecting scalar integers larger than 16 bytes!");
18158 else if (
Size == 32)
18165 else if (
Size == 256) {
18166 assert(Subtarget.pairedVectorMemops() &&
18167 "256-bit vectors are only available when paired vector memops is "
18175 else if (MemVT == MVT::f128 || MemVT.
isVector())
18185 if (
const LoadSDNode *LN = dyn_cast<LoadSDNode>(Parent)) {
18206 FlagSet &= ~PPC::MOF_NoExt;
18211 bool IsNonP1034BitConst =
18215 IsNonP1034BitConst)
18228 int16_t ForceXFormImm = 0;
18231 Disp =
N.getOperand(0);
18232 Base =
N.getOperand(1);
18243 !
N.getOperand(1).hasOneUse() || !
N.getOperand(0).hasOneUse())) {
18244 Disp =
N.getOperand(0);
18245 Base =
N.getOperand(1);
18259 unsigned NumParts,
MVT PartVT, std::optional<CallingConv::ID>
CC)
const {
18265 if (PartVT == MVT::f64 &&
18266 (ValVT == MVT::i32 || ValVT == MVT::i16 || ValVT == MVT::i8)) {
18275SDValue PPCTargetLowering::lowerToLibCall(
const char *LibCallName,
SDValue Op,
18279 EVT RetVT =
Op.getValueType();
18287 EVT ArgVT =
N.getValueType();
18292 Entry.IsZExt = !Entry.IsSExt;
18293 Args.push_back(Entry);
18301 (
RetTy ==
F.getReturnType() ||
F.getReturnType()->isVoidTy());
18307 .setTailCall(isTailCall)
18314SDValue PPCTargetLowering::lowerLibCallBasedOnType(
18315 const char *LibCallFloatName,
const char *LibCallDoubleName,
SDValue Op,
18317 if (
Op.getValueType() == MVT::f32)
18318 return lowerToLibCall(LibCallFloatName,
Op, DAG);
18320 if (
Op.getValueType() == MVT::f64)
18321 return lowerToLibCall(LibCallDoubleName,
Op, DAG);
18326bool PPCTargetLowering::isLowringToMASSFiniteSafe(
SDValue Op)
const {
18328 return isLowringToMASSSafe(
Op) &&
Flags.hasNoSignedZeros() &&
18332bool PPCTargetLowering::isLowringToMASSSafe(
SDValue Op)
const {
18333 return Op.getNode()->getFlags().hasApproximateFuncs();
18336bool PPCTargetLowering::isScalarMASSConversionEnabled()
const {
18340SDValue PPCTargetLowering::lowerLibCallBase(
const char *LibCallDoubleName,
18341 const char *LibCallFloatName,
18342 const char *LibCallDoubleNameFinite,
18343 const char *LibCallFloatNameFinite,
18346 if (!isScalarMASSConversionEnabled() || !isLowringToMASSSafe(
Op))
18349 if (!isLowringToMASSFiniteSafe(
Op))
18350 return lowerLibCallBasedOnType(LibCallFloatName, LibCallDoubleName,
Op,
18353 return lowerLibCallBasedOnType(LibCallFloatNameFinite,
18354 LibCallDoubleNameFinite,
Op, DAG);
18358 return lowerLibCallBase(
"__xl_pow",
"__xl_powf",
"__xl_pow_finite",
18359 "__xl_powf_finite",
Op, DAG);
18363 return lowerLibCallBase(
"__xl_sin",
"__xl_sinf",
"__xl_sin_finite",
18364 "__xl_sinf_finite",
Op, DAG);
18368 return lowerLibCallBase(
"__xl_cos",
"__xl_cosf",
"__xl_cos_finite",
18369 "__xl_cosf_finite",
Op, DAG);
18373 return lowerLibCallBase(
"__xl_log",
"__xl_logf",
"__xl_log_finite",
18374 "__xl_logf_finite",
Op, DAG);
18378 return lowerLibCallBase(
"__xl_log10",
"__xl_log10f",
"__xl_log10_finite",
18379 "__xl_log10f_finite",
Op, DAG);
18383 return lowerLibCallBase(
"__xl_exp",
"__xl_expf",
"__xl_exp_finite",
18384 "__xl_expf_finite",
Op, DAG);
18391 if (!isa<FrameIndexSDNode>(
N))
18409 unsigned Flags = computeMOFlags(Parent,
N, DAG);
18421 "Must be using PC-Relative calls when a valid PC-Relative node is "
18451 Disp =
N.getOperand(1).getOperand(0);
18456 Base =
N.getOperand(0);
18463 auto *CN = cast<ConstantSDNode>(
N);
18464 EVT CNType = CN->getValueType(0);
18465 uint64_t CNImm = CN->getZExtValue();
18476 if ((CNType == MVT::i32 || isInt<32>(CNImm)) &&
18478 int32_t
Addr = (int32_t)CNImm;
18483 uint32_t LIS = CNType == MVT::i32 ? PPC::LIS : PPC::LIS8;
18499 unsigned Opcode =
N.getOpcode();
18507 Base =
N.getOperand(0);
18526 Base = FI ?
N :
N.getOperand(1);
18538 bool IsVarArg)
const {
18548 return Subtarget.
isPPC64() && Subtarget.hasQuadwordAtomics();
18582 return Intrinsic::ppc_atomicrmw_xchg_i128;
18584 return Intrinsic::ppc_atomicrmw_add_i128;
18586 return Intrinsic::ppc_atomicrmw_sub_i128;
18588 return Intrinsic::ppc_atomicrmw_and_i128;
18590 return Intrinsic::ppc_atomicrmw_or_i128;
18592 return Intrinsic::ppc_atomicrmw_xor_i128;
18594 return Intrinsic::ppc_atomicrmw_nand_i128;
18611 Value *LoHi = Builder.
CreateCall(RMW, {AlignedAddr, IncrLo, IncrHi});
18638 Builder.
CreateCall(IntCmpXchg, {AlignedAddr, CmpLo, CmpHi, NewLo, NewHi});
unsigned const MachineRegisterInfo * MRI
static unsigned getCallOpcode(const MachineFunction &CallerF, bool IsIndirect, bool IsTailCall)
static SDValue GeneratePerfectShuffle(unsigned ID, SDValue V1, SDValue V2, unsigned PFEntry, SDValue LHS, SDValue RHS, SelectionDAG &DAG, const SDLoc &dl)
GeneratePerfectShuffle - Given an entry in the perfect-shuffle table, emit the specified operations t...
static bool isSignExtended(SDValue N, SelectionDAG &DAG)
static const unsigned PerfectShuffleTable[6561+1]
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL
static std::pair< Register, unsigned > getBaseWithConstantOffset(MachineRegisterInfo &MRI, Register Reg)
This file declares a class to represent arbitrary precision floating point values and provide a varie...
This file implements a class to represent arbitrary precision integral constant values and operations...
This file implements the APSInt class, which is a simple class that represents an arbitrary sized int...
static bool isLoad(int Opcode)
static bool isFloatingPointZero(SDValue Op)
isFloatingPointZero - Return true if this is +0.0.
Function Alias Analysis Results
Atomic ordering constants.
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
Analysis containing CSE Info
This file contains the declarations for the subclasses of Constant, which represent the different fla...
Returns the sub type a function will return at a given Idx Should correspond to the result type of an ExtractValue instruction executed with just that one unsigned Idx
Given that RA is a live propagate it s liveness to any other values it uses(according to Uses). void DeadArgumentEliminationPass
static RegisterPass< DebugifyModulePass > DM("debugify", "Attach debug info to everything")
This file defines the DenseMap class.
static GCMetadataPrinterRegistry::Add< ErlangGCPrinter > X("erlang", "erlang-compatible garbage collector")
const HexagonInstrInfo * TII
static SDValue CreateCopyOfByValArgument(SDValue Src, SDValue Dst, SDValue Chain, ISD::ArgFlagsTy Flags, SelectionDAG &DAG, const SDLoc &dl)
CreateCopyOfByValArgument - Make a copy of an aggregate at address specified by "Src" to address "Dst...
static bool isConstantOrUndef(const SDValue Op)
static bool isSplat(Value *V)
Return true if V is a splat of a value (which is used when multiplying a matrix with a scalar).
unsigned const TargetRegisterInfo * TRI
Module.h This file contains the declarations for the Module class.
static GCMetadataPrinterRegistry::Add< OcamlGCMetadataPrinter > Y("ocaml", "ocaml 3.10-compatible collector")
cl::opt< bool > ANDIGlueBug("expose-ppc-andi-glue-bug", cl::desc("expose the ANDI glue bug on PPC"), cl::Hidden)
static SDValue getCanonicalConstSplat(uint64_t Val, unsigned SplatSize, EVT VT, SelectionDAG &DAG, const SDLoc &dl)
getCanonicalConstSplat - Build a canonical splat immediate of Val with an element size of SplatSize.
static const TargetRegisterClass * getRegClassForSVT(MVT::SimpleValueType SVT, bool IsPPC64, bool HasP8Vector, bool HasVSX)
static bool isGPRShadowAligned(MCPhysReg Reg, Align RequiredAlign)
static bool needStackSlotPassParameters(const PPCSubtarget &Subtarget, const SmallVectorImpl< ISD::OutputArg > &Outs)
static bool isAlternatingShuffMask(const ArrayRef< int > &Mask, int NumElts)
static SDValue addShuffleForVecExtend(SDNode *N, SelectionDAG &DAG, SDValue Input, uint64_t Elems, uint64_t CorrectElems)
static cl::opt< bool > DisablePPCUnaligned("disable-ppc-unaligned", cl::desc("disable unaligned load/store generation on PPC"), cl::Hidden)
static SDValue combineADDToADDZE(SDNode *N, SelectionDAG &DAG, const PPCSubtarget &Subtarget)
static bool findConsecutiveLoad(LoadSDNode *LD, SelectionDAG &DAG)
static SDValue generateEquivalentSub(SDNode *N, int Size, bool Complement, bool Swap, SDLoc &DL, SelectionDAG &DAG)
This function is called when we have proved that a SETCC node can be replaced by subtraction (and oth...
static unsigned mapArgRegToOffsetAIX(unsigned Reg, const PPCFrameLowering *FL)
static SDValue combineADDToMAT_PCREL_ADDR(SDNode *N, SelectionDAG &DAG, const PPCSubtarget &Subtarget)
static void setAlignFlagsForFI(SDValue N, unsigned &FlagSet, SelectionDAG &DAG)
Set alignment flags based on whether or not the Frame Index is aligned.
static bool isTOCSaveRestoreRequired(const PPCSubtarget &Subtarget)
static bool provablyDisjointOr(SelectionDAG &DAG, const SDValue &N)
Used when computing address flags for selecting loads and stores.
static void CalculateTailCallArgDest(SelectionDAG &DAG, MachineFunction &MF, bool isPPC64, SDValue Arg, int SPDiff, unsigned ArgOffset, SmallVectorImpl< TailCallArgumentInfo > &TailCallArguments)
CalculateTailCallArgDest - Remember Argument for later processing.
static bool callsShareTOCBase(const Function *Caller, const GlobalValue *CalleeGV, const TargetMachine &TM)
constexpr uint64_t AIXSmallTlsPolicySizeLimit
static bool isPCRelNode(SDValue N)
static void LowerMemOpCallTo(SelectionDAG &DAG, MachineFunction &MF, SDValue Chain, SDValue Arg, SDValue PtrOff, int SPDiff, unsigned ArgOffset, bool isPPC64, bool isTailCall, bool isVector, SmallVectorImpl< SDValue > &MemOpChains, SmallVectorImpl< TailCallArgumentInfo > &TailCallArguments, const SDLoc &dl)
LowerMemOpCallTo - Store the argument to the stack or remember it in case of tail calls.
static bool areCallingConvEligibleForTCO_64SVR4(CallingConv::ID CallerCC, CallingConv::ID CalleeCC)
static const MCPhysReg FPR[]
FPR - The set of FP registers that should be allocated for arguments on Darwin and AIX.
static SDNode * isBLACompatibleAddress(SDValue Op, SelectionDAG &DAG)
isCallCompatibleAddress - Return the immediate to use if the specified 32-bit value is representable ...
static Align CalculateStackSlotAlignment(EVT ArgVT, EVT OrigVT, ISD::ArgFlagsTy Flags, unsigned PtrByteSize)
CalculateStackSlotAlignment - Calculates the alignment of this argument on the stack.
static bool haveEfficientBuildVectorPattern(BuildVectorSDNode *V, bool HasDirectMove, bool HasP8Vector)
Do we have an efficient pattern in a .td file for this node?
static SDValue getSToVPermuted(SDValue OrigSToV, SelectionDAG &DAG, const PPCSubtarget &Subtarget)
static bool CC_AIX(unsigned ValNo, MVT ValVT, MVT LocVT, CCValAssign::LocInfo LocInfo, ISD::ArgFlagsTy ArgFlags, CCState &S)
static void setUsesTOCBasePtr(MachineFunction &MF)
static SDValue transformCallee(const SDValue &Callee, SelectionDAG &DAG, const SDLoc &dl, const PPCSubtarget &Subtarget)
static unsigned EnsureStackAlignment(const PPCFrameLowering *Lowering, unsigned NumBytes)
EnsureStackAlignment - Round stack frame size up from NumBytes to ensure minimum alignment required f...
static SDValue stripModuloOnShift(const TargetLowering &TLI, SDNode *N, SelectionDAG &DAG)
static bool isStoreConditional(SDValue Intrin, unsigned &StoreWidth)
static bool hasSameArgumentList(const Function *CallerFn, const CallBase &CB)
static bool isFPExtLoad(SDValue Op)
static SDValue BuildIntrinsicOp(unsigned IID, SDValue Op, SelectionDAG &DAG, const SDLoc &dl, EVT DestVT=MVT::Other)
BuildIntrinsicOp - Return a unary operator intrinsic node with the specified intrinsic ID.
static bool isConsecutiveLSLoc(SDValue Loc, EVT VT, LSBaseSDNode *Base, unsigned Bytes, int Dist, SelectionDAG &DAG)
static void StoreTailCallArgumentsToStackSlot(SelectionDAG &DAG, SDValue Chain, const SmallVectorImpl< TailCallArgumentInfo > &TailCallArgs, SmallVectorImpl< SDValue > &MemOpChains, const SDLoc &dl)
StoreTailCallArgumentsToStackSlot - Stores arguments to their stack slot.
static const char AIXSSPCanaryWordName[]
static cl::opt< bool > UseAbsoluteJumpTables("ppc-use-absolute-jumptables", cl::desc("use absolute jump tables on ppc"), cl::Hidden)
static void setXFormForUnalignedFI(SDValue N, unsigned Flags, PPC::AddrMode &Mode)
static void getMaxByValAlign(Type *Ty, Align &MaxAlign, Align MaxMaxAlign)
getMaxByValAlign - Helper for getByValTypeAlignment to determine the desired ByVal argument alignment...
static bool isConsecutiveLS(SDNode *N, LSBaseSDNode *Base, unsigned Bytes, int Dist, SelectionDAG &DAG)
static bool isVMerge(ShuffleVectorSDNode *N, unsigned UnitSize, unsigned LHSStart, unsigned RHSStart)
isVMerge - Common function, used to match vmrg* shuffles.
static void getLabelAccessInfo(bool IsPIC, const PPCSubtarget &Subtarget, unsigned &HiOpFlags, unsigned &LoOpFlags, const GlobalValue *GV=nullptr)
Return true if we should reference labels using a PICBase, set the HiOpFlags and LoOpFlags to the tar...
cl::opt< bool > DisableAutoPairedVecSt("disable-auto-paired-vec-st", cl::desc("disable automatically generated 32byte paired vector stores"), cl::init(true), cl::Hidden)
static void buildCallOperands(SmallVectorImpl< SDValue > &Ops, PPCTargetLowering::CallFlags CFlags, const SDLoc &dl, SelectionDAG &DAG, SmallVector< std::pair< unsigned, SDValue >, 8 > &RegsToPass, SDValue Glue, SDValue Chain, SDValue &Callee, int SPDiff, const PPCSubtarget &Subtarget)
static cl::opt< bool > DisableInnermostLoopAlign32("disable-ppc-innermost-loop-align32", cl::desc("don't always align innermost loop to 32 bytes on ppc"), cl::Hidden)
static bool usePartialVectorLoads(SDNode *N, const PPCSubtarget &ST)
Returns true if we should use a direct load into vector instruction (such as lxsd or lfd),...
static SDValue getDataClassTest(SDValue Op, FPClassTest Mask, const SDLoc &Dl, SelectionDAG &DAG, const PPCSubtarget &Subtarget)
static cl::opt< bool > DisableSCO("disable-ppc-sco", cl::desc("disable sibling call optimization on ppc"), cl::Hidden)
static void fixupFuncForFI(SelectionDAG &DAG, int FrameIdx, EVT VT)
static cl::opt< bool > DisablePPCPreinc("disable-ppc-preinc", cl::desc("disable preincrement load/store generation on PPC"), cl::Hidden)
static Intrinsic::ID getIntrinsicForAtomicRMWBinOp128(AtomicRMWInst::BinOp BinOp)
static SDValue convertFPToInt(SDValue Op, SelectionDAG &DAG, const PPCSubtarget &Subtarget)
static unsigned CalculateStackSlotSize(EVT ArgVT, ISD::ArgFlagsTy Flags, unsigned PtrByteSize)
CalculateStackSlotSize - Calculates the size reserved for this argument on the stack.
static int CalculateTailCallSPDiff(SelectionDAG &DAG, bool isTailCall, unsigned ParamSize)
CalculateTailCallSPDiff - Get the amount the stack pointer has to be adjusted to accommodate the argu...
static Instruction * callIntrinsic(IRBuilderBase &Builder, Intrinsic::ID Id)
static void fixupShuffleMaskForPermutedSToV(SmallVectorImpl< int > &ShuffV, int LHSMaxIdx, int RHSMinIdx, int RHSMaxIdx, int HalfVec, unsigned ValidLaneWidth, const PPCSubtarget &Subtarget)
static void prepareIndirectCall(SelectionDAG &DAG, SDValue &Callee, SDValue &Glue, SDValue &Chain, const SDLoc &dl)
static SDValue LowerLabelRef(SDValue HiPart, SDValue LoPart, bool isPIC, SelectionDAG &DAG)
static SDValue isScalarToVec(SDValue Op)
static SDValue widenVec(SelectionDAG &DAG, SDValue Vec, const SDLoc &dl)
static cl::opt< bool > DisablePerfectShuffle("ppc-disable-perfect-shuffle", cl::desc("disable vector permute decomposition"), cl::init(true), cl::Hidden)
static bool getVectorCompareInfo(SDValue Intrin, int &CompareOpc, bool &isDot, const PPCSubtarget &Subtarget)
getVectorCompareInfo - Given an intrinsic, return false if it is not a vector comparison.
static unsigned invertFMAOpcode(unsigned Opc)
static const SDValue * getNormalLoadInput(const SDValue &Op, bool &IsPermuted)
static cl::opt< unsigned > PPCMinimumJumpTableEntries("ppc-min-jump-table-entries", cl::init(64), cl::Hidden, cl::desc("Set minimum number of entries to use a jump table on PPC"))
static bool isValidSplatLoad(const PPCSubtarget &Subtarget, const SDValue &Op, unsigned &Opcode)
static SDValue convertIntToFP(SDValue Op, SDValue Src, SelectionDAG &DAG, const PPCSubtarget &Subtarget, SDValue Chain=SDValue())
static int getEstimateRefinementSteps(EVT VT, const PPCSubtarget &Subtarget)
static void PrepareTailCall(SelectionDAG &DAG, SDValue &InGlue, SDValue &Chain, const SDLoc &dl, int SPDiff, unsigned NumBytes, SDValue LROp, SDValue FPOp, SmallVectorImpl< TailCallArgumentInfo > &TailCallArguments)
static SDValue EmitTailCallStoreFPAndRetAddr(SelectionDAG &DAG, SDValue Chain, SDValue OldRetAddr, SDValue OldFP, int SPDiff, const SDLoc &dl)
EmitTailCallStoreFPAndRetAddr - Move the frame pointer and return address to the appropriate stack sl...
static SDValue BuildVSLDOI(SDValue LHS, SDValue RHS, unsigned Amt, EVT VT, SelectionDAG &DAG, const SDLoc &dl)
BuildVSLDOI - Return a VECTOR_SHUFFLE that is a vsldoi of the specified amount.
static SDValue combineBVZEXTLOAD(SDNode *N, SelectionDAG &DAG)
static SDValue truncateScalarIntegerArg(ISD::ArgFlagsTy Flags, EVT ValVT, SelectionDAG &DAG, SDValue ArgValue, MVT LocVT, const SDLoc &dl)
static void computeFlagsForAddressComputation(SDValue N, unsigned &FlagSet, SelectionDAG &DAG)
Given a node, compute flags that are used for address computation when selecting load and store instr...
cl::opt< bool > ANDIGlueBug
static SDValue getOutputChainFromCallSeq(SDValue CallSeqStart)
static bool CalculateStackSlotUsed(EVT ArgVT, EVT OrigVT, ISD::ArgFlagsTy Flags, unsigned PtrByteSize, unsigned LinkageSize, unsigned ParamAreaSize, unsigned &ArgOffset, unsigned &AvailableFPRs, unsigned &AvailableVRs)
CalculateStackSlotUsed - Return whether this argument will use its stack slot (instead of being passe...
static unsigned getPPCStrictOpcode(unsigned Opc)
static void prepareDescriptorIndirectCall(SelectionDAG &DAG, SDValue &Callee, SDValue &Glue, SDValue &Chain, SDValue CallSeqStart, const CallBase *CB, const SDLoc &dl, bool hasNest, const PPCSubtarget &Subtarget)
static bool isXXBRShuffleMaskHelper(ShuffleVectorSDNode *N, int Width)
static bool isFunctionGlobalAddress(const GlobalValue *CalleeGV)
static bool isSplatBV(SDValue Op)
static SDValue combineBVOfVecSExt(SDNode *N, SelectionDAG &DAG)
static cl::opt< bool > DisableILPPref("disable-ppc-ilp-pref", cl::desc("disable setting the node scheduling preference to ILP on PPC"), cl::Hidden)
static bool isNByteElemShuffleMask(ShuffleVectorSDNode *, unsigned, int)
Check that the mask is shuffling N byte elements.
static SDValue combineBVOfConsecutiveLoads(SDNode *N, SelectionDAG &DAG)
Reduce the number of loads when building a vector.
static bool isValidPCRelNode(SDValue N)
const char LLVMTargetMachineRef TM
pre isel intrinsic Pre ISel Intrinsic Lowering
const SmallVectorImpl< MachineOperand > & Cond
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
SI optimize exec mask operations pre RA
This file defines the SmallPtrSet class.
This file defines the SmallSet class.
This file defines the SmallVector class.
This file defines the 'Statistic' class, which is designed to be an easy way to expose various metric...
#define STATISTIC(VARNAME, DESC)
This file implements the StringSwitch template, which mimics a switch() statement whose cases are str...
This file describes how to lower LLVM code to machine code.
This defines the Use class.
static bool contains(SmallPtrSetImpl< ConstantExpr * > &Cache, ConstantExpr *Expr, Constant *C)
static bool is64Bit(const char *name)
bool isFixed(unsigned ValNo) const
opStatus convert(const fltSemantics &ToSemantics, roundingMode RM, bool *losesInfo)
APInt bitcastToAPInt() const
Class for arbitrary precision integers.
static APInt getAllOnes(unsigned numBits)
Return an APInt of a specified width with all bits set.
void clearBit(unsigned BitPosition)
Set a given bit to 0.
bool isNegatedPowerOf2() const
Check if this APInt's negated value is a power of two greater than zero.
APInt zext(unsigned width) const
Zero extend to a new width.
uint64_t getZExtValue() const
Get zero extended value.
void setBit(unsigned BitPosition)
Set the given bit to 1 whose position is given as "bitPosition".
APInt abs() const
Get the absolute value.
bool isNegative() const
Determine sign of this APInt.
bool isSignedIntN(unsigned N) const
Check if this APInt has an N-bits signed integer value.
bool getBoolValue() const
Convert APInt to a boolean value.
double bitsToDouble() const
Converts APInt bits to a double.
bool isPowerOf2() const
Check if this APInt's value is a power of two greater than zero.
static APInt getLowBitsSet(unsigned numBits, unsigned loBitsSet)
Constructs an APInt value that has the bottom loBitsSet bits set.
static APInt getHighBitsSet(unsigned numBits, unsigned hiBitsSet)
Constructs an APInt value that has the top hiBitsSet bits set.
An arbitrary precision integer that knows its signedness.
This class represents an incoming formal argument to a Function.
ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory),...
size_t size() const
size - Get the array size.
An instruction that atomically checks whether a specified value is in a memory location,...
Value * getNewValOperand()
an instruction that atomically reads a memory location, combines it with another value,...
BinOp
This enumeration lists the possible modifications atomicrmw can make.
@ UIncWrap
Increment one up to a maximum value.
@ UDecWrap
Decrement one until a minimum value or zero.
BinOp getOperation() const
This is an SDNode representing atomic operations.
StringRef getValueAsString() const
Return the attribute's value as a string.
LLVM Basic Block Representation.
const Function * getParent() const
Return the enclosing method, or null if none.
int64_t getOffset() const
const BlockAddress * getBlockAddress() const
The address of a basic block.
static BranchProbability getOne()
static BranchProbability getZero()
A "pseudo-class" with methods for operating on BUILD_VECTORs.
bool isConstantSplat(APInt &SplatValue, APInt &SplatUndef, unsigned &SplatBitSize, bool &HasAnyUndefs, unsigned MinSplatBits=0, bool isBigEndian=false) const
Check if this is a constant splat, and if so, find the smallest element size that splats the vector.
CCState - This class holds information needed while lowering arguments and return values.
MachineFunction & getMachineFunction() const
unsigned getFirstUnallocated(ArrayRef< MCPhysReg > Regs) const
getFirstUnallocated - Return the index of the first unallocated register in the set,...
MCRegister AllocateReg(MCPhysReg Reg)
AllocateReg - Attempt to allocate one register.
int64_t AllocateStack(unsigned Size, Align Alignment)
AllocateStack - Allocate a chunk of stack space with the specified size and alignment.
uint64_t getStackSize() const
Returns the size of the currently allocated portion of the stack.
void addLoc(const CCValAssign &V)
CCValAssign - Represent assignment of one arg/retval to a location.
Register getLocReg() const
LocInfo getLocInfo() const
static CCValAssign getMem(unsigned ValNo, MVT ValVT, int64_t Offset, MVT LocVT, LocInfo HTP, bool IsCustom=false)
static CCValAssign getReg(unsigned ValNo, MVT ValVT, unsigned RegNo, MVT LocVT, LocInfo HTP, bool IsCustom=false)
static CCValAssign getCustomReg(unsigned ValNo, MVT ValVT, unsigned RegNo, MVT LocVT, LocInfo HTP)
int64_t getLocMemOffset() const
unsigned getValNo() const
static CCValAssign getCustomMem(unsigned ValNo, MVT ValVT, int64_t Offset, MVT LocVT, LocInfo HTP)
Base class for all callable instructions (InvokeInst and CallInst) Holds everything related to callin...
Function * getCalledFunction() const
Returns the function called, or null if this is an indirect function invocation or the function signa...
bool isStrictFP() const
Determine if the call requires strict floating point semantics.
CallingConv::ID getCallingConv() const
User::op_iterator arg_begin()
Return the iterator pointing to the beginning of the argument list.
bool isMustTailCall() const
Tests if this call site must be tail call optimized.
Value * getCalledOperand() const
User::op_iterator arg_end()
Return the iterator pointing to the end of the argument list.
unsigned arg_size() const
Function * getCaller()
Helper to get the caller (the parent function).
This class represents a function call, abstracting a target machine's calling convention.
ConstantFP - Floating Point Values [float, double].
This is the shared class of boolean and integer constants.
static Constant * get(Type *Ty, uint64_t V, bool IsSigned=false)
If Ty is a vector type, return a Constant with a splat of the given value.
uint64_t getZExtValue() const
const APInt & getAPIntValue() const
int64_t getSExtValue() const
This is an important base class in LLVM.
This class represents an Operation in the Expression.
uint64_t getNumOperands() const
A parsed version of the target data layout string in and methods for querying it.
bool isLittleEndian() const
Layout endianness...
unsigned getLargestLegalIntTypeSizeInBits() const
Returns the size of largest legal integer type size, or 0 if none are set.
IntegerType * getIntPtrType(LLVMContext &C, unsigned AddressSpace=0) const
Returns an integer type with size at least as big as that of a pointer in the given address space.
Align getABITypeAlign(Type *Ty) const
Returns the minimum ABI-required alignment for the specified type.
TypeSize getTypeAllocSize(Type *Ty) const
Returns the offset in bytes between successive objects of the specified type, including alignment pad...
iterator find(const_arg_type_t< KeyT > Val)
std::pair< iterator, bool > insert(const std::pair< KeyT, ValueT > &KV)
This is a fast-path instruction selection class that generates poor code and doesn't support illegal ...
FunctionLoweringInfo - This contains information that is global to a function that is used when lower...
bool hasOptSize() const
Optimize this function for size (-Os) or minimum size (-Oz).
Attribute getFnAttribute(Attribute::AttrKind Kind) const
Return the attribute for the given attribute kind.
uint64_t getFnAttributeAsParsedInteger(StringRef Kind, uint64_t Default=0) const
For a string attribute Kind, parse attribute as an integer.
bool hasMinSize() const
Optimize this function for minimum size (-Oz).
CallingConv::ID getCallingConv() const
getCallingConv()/setCallingConv(CC) - These method get and set the calling convention of this functio...
AttributeList getAttributes() const
Return the attribute list for this Function.
LLVMContext & getContext() const
getContext - Return a reference to the LLVMContext associated with this function.
Type * getReturnType() const
Returns the type of the ret val.
bool isVarArg() const
isVarArg - Return true if this function takes a variable number of arguments.
bool hasFnAttribute(Attribute::AttrKind Kind) const
Return true if the function has the attribute.
int64_t getOffset() const
unsigned getTargetFlags() const
const GlobalValue * getGlobal() const
const GlobalObject * getAliaseeObject() const
bool isThreadLocal() const
If the value is "Thread Local", its value isn't shared by the threads.
bool hasHiddenVisibility() const
StringRef getSection() const
Module * getParent()
Get the module that this global value is contained inside of...
bool isStrongDefinitionForLinker() const
Returns true if this global's definition will be the one chosen by the linker.
Type * getValueType() const
bool hasProtectedVisibility() const
Common base class shared among various IRBuilders.
Value * CreateTrunc(Value *V, Type *DestTy, const Twine &Name="")
Value * CreateExtractValue(Value *Agg, ArrayRef< unsigned > Idxs, const Twine &Name="")
Value * CreateLShr(Value *LHS, Value *RHS, const Twine &Name="", bool isExact=false)
BasicBlock * GetInsertBlock() const
Value * CreateShl(Value *LHS, Value *RHS, const Twine &Name="", bool HasNUW=false, bool HasNSW=false)
Value * CreateZExt(Value *V, Type *DestTy, const Twine &Name="", bool IsNonNeg=false)
Value * CreateOr(Value *LHS, Value *RHS, const Twine &Name="")
CallInst * CreateCall(FunctionType *FTy, Value *Callee, ArrayRef< Value * > Args=std::nullopt, const Twine &Name="", MDNode *FPMathTag=nullptr)
const BasicBlock * getParent() const
bool hasAtomicLoad() const LLVM_READONLY
Return true if this atomic instruction loads from memory.
static constexpr LLT scalar(unsigned SizeInBits)
Get a low-level scalar or aggregate "bag of bits".
This is an important class for using LLVM in a threaded context.
Base class for LoadSDNode and StoreSDNode.
An instruction for reading from memory.
This class is used to represent ISD::LOAD nodes.
const SDValue & getBasePtr() const
ISD::LoadExtType getExtensionType() const
Return whether this is a plain node, or one of the varieties of value-extending loads.
Context object for machine code objects.
Base class for the full range of assembler expressions which are needed for parsing.
Wrapper class representing physical registers. Should be passed by value.
MCSymbolXCOFF * getQualNameSymbol() const
static const MCSymbolRefExpr * create(const MCSymbol *Symbol, MCContext &Ctx)
@ INVALID_SIMPLE_VALUE_TYPE
unsigned getVectorNumElements() const
bool isVector() const
Return true if this is a vector value type.
bool isInteger() const
Return true if this is an integer or a vector integer type.
static auto integer_valuetypes()
TypeSize getSizeInBits() const
Returns the size of the specified MVT in bits.
static auto fixedlen_vector_valuetypes()
uint64_t getFixedSizeInBits() const
Return the size of the specified fixed width value type in bits.
TypeSize getStoreSize() const
Return the number of bytes overwritten by a store of the specified value type.
bool isScalarInteger() const
Return true if this is an integer, not including vectors.
bool isFloatingPoint() const
Return true if this is a FP or a vector FP type.
static MVT getIntegerVT(unsigned BitWidth)
static auto fp_valuetypes()
void transferSuccessorsAndUpdatePHIs(MachineBasicBlock *FromMBB)
Transfers all the successors, as in transferSuccessors, and update PHI operands in the successor bloc...
const BasicBlock * getBasicBlock() const
Return the LLVM basic block that this instance corresponded to originally.
void addSuccessor(MachineBasicBlock *Succ, BranchProbability Prob=BranchProbability::getUnknown())
Add Succ as a successor of this MachineBasicBlock.
const MachineFunction * getParent() const
Return the MachineFunction containing this basic block.
void splice(iterator Where, MachineBasicBlock *Other, iterator From)
Take an instruction from MBB 'Other' at the position From, and insert it into this MBB right before '...
The MachineFrameInfo class represents an abstract stack frame until prolog/epilog code is inserted.
int CreateFixedObject(uint64_t Size, int64_t SPOffset, bool IsImmutable, bool isAliased=false)
Create a new object at a fixed location on the stack.
int CreateStackObject(uint64_t Size, Align Alignment, bool isSpillSlot, const AllocaInst *Alloca=nullptr, uint8_t ID=0)
Create a new statically sized stack object, returning a nonnegative identifier to represent it.
void setFrameAddressIsTaken(bool T)
void setHasTailCall(bool V=true)
void setReturnAddressIsTaken(bool s)
Align getObjectAlign(int ObjectIdx) const
Return the alignment of the specified stack object.
int64_t getObjectSize(int ObjectIdx) const
Return the size of the specified object.
bool hasVAStart() const
Returns true if the function calls the llvm.va_start intrinsic.
int64_t getObjectOffset(int ObjectIdx) const
Return the assigned stack offset of the specified object from the incoming stack pointer.
MachineMemOperand * getMachineMemOperand(MachinePointerInfo PtrInfo, MachineMemOperand::Flags f, uint64_t s, Align base_alignment, const AAMDNodes &AAInfo=AAMDNodes(), const MDNode *Ranges=nullptr, SyncScope::ID SSID=SyncScope::System, AtomicOrdering Ordering=AtomicOrdering::NotAtomic, AtomicOrdering FailureOrdering=AtomicOrdering::NotAtomic)
getMachineMemOperand - Allocate a new MachineMemOperand.
MCSymbol * getPICBaseSymbol() const
getPICBaseSymbol - Return a function-local symbol to represent the PIC base.
const TargetSubtargetInfo & getSubtarget() const
getSubtarget - Return the subtarget for which this machine code is being compiled.
StringRef getName() const
getName - Return the name of the corresponding LLVM function.
MachineFrameInfo & getFrameInfo()
getFrameInfo - Return the frame info object for the current function.
MachineRegisterInfo & getRegInfo()
getRegInfo - Return information about the registers currently in use.
const DataLayout & getDataLayout() const
Return the DataLayout attached to the Module associated to this MF.
Function & getFunction()
Return the LLVM function that this machine code represents.
MachineModuleInfo & getMMI() const
Ty * getInfo()
getInfo - Keep track of various per-function pieces of information for backends that would like to do...
Register addLiveIn(MCRegister PReg, const TargetRegisterClass *RC)
addLiveIn - Add the specified physical register as a live-in value and create a corresponding virtual...
MachineBasicBlock * CreateMachineBasicBlock(const BasicBlock *BB=nullptr, std::optional< UniqueBBID > BBID=std::nullopt)
CreateMachineBasicBlock - Allocate a new MachineBasicBlock.
void insert(iterator MBBI, MachineBasicBlock *MBB)
const MachineInstrBuilder & setMIFlag(MachineInstr::MIFlag Flag) const
const MachineInstrBuilder & addImm(int64_t Val) const
Add a new immediate operand.
const MachineInstrBuilder & add(const MachineOperand &MO) const
const MachineInstrBuilder & addFrameIndex(int Idx) const
const MachineInstrBuilder & addRegMask(const uint32_t *Mask) const
const MachineInstrBuilder & addReg(Register RegNo, unsigned flags=0, unsigned SubReg=0) const
Add a new virtual register operand.
const MachineInstrBuilder & addMBB(MachineBasicBlock *MBB, unsigned TargetFlags=0) const
const MachineInstrBuilder & cloneMemRefs(const MachineInstr &OtherMI) const
const MachineInstrBuilder & addUse(Register RegNo, unsigned Flags=0, unsigned SubReg=0) const
Add a virtual register use operand.
const MachineInstrBuilder & addMemOperand(MachineMemOperand *MMO) const
const MachineInstrBuilder & addDef(Register RegNo, unsigned Flags=0, unsigned SubReg=0) const
Add a virtual register definition operand.
Representation of each machine instruction.
@ EK_LabelDifference32
EK_LabelDifference32 - Each entry is the address of the block minus the address of the jump table.
A description of a memory reference used in the backend.
uint64_t getSize() const
Return the size in bytes of the memory reference.
Flags
Flags values. These may be or'd together.
@ MOVolatile
The memory access is volatile.
@ MODereferenceable
The memory access is dereferenceable (i.e., doesn't trap).
@ MOLoad
The memory access reads data.
@ MOInvariant
The memory access always returns the same value (or traps).
@ MOStore
The memory access writes data.
Flags getFlags() const
Return the raw flags of the source value,.
const MCContext & getContext() const
MachineOperand class - Representation of each machine instruction operand.
static MachineOperand CreateImm(int64_t Val)
static MachineOperand CreateReg(Register Reg, bool isDef, bool isImp=false, bool isKill=false, bool isDead=false, bool isUndef=false, bool isEarlyClobber=false, unsigned SubReg=0, bool isDebug=false, bool isInternalRead=false, bool isRenamable=false)
MachineRegisterInfo - Keep track of information for virtual and physical registers,...
const TargetRegisterClass * getRegClass(Register Reg) const
Return the register class of the specified virtual register.
MachineInstr * getVRegDef(Register Reg) const
getVRegDef - Return the machine instr that defines the specified virtual register or null if none is ...
Register createVirtualRegister(const TargetRegisterClass *RegClass, StringRef Name="")
createVirtualRegister - Create and return a new virtual register in the function with the specified r...
Register getLiveInVirtReg(MCRegister PReg) const
getLiveInVirtReg - If PReg is a live-in physical register, return the corresponding live-in virtual r...
An SDNode that represents everything that will be needed to construct a MachineInstr.
This SDNode is used for target intrinsics that touch memory and need an associated MachineMemOperand.
This is an abstract virtual class for memory operations.
AAMDNodes getAAInfo() const
Returns the AA info that describes the dereference.
MachineMemOperand * getMemOperand() const
Return a MachineMemOperand object describing the memory reference performed by operation.
const SDValue & getBasePtr() const
const MachinePointerInfo & getPointerInfo() const
const SDValue & getChain() const
EVT getMemoryVT() const
Return the type of the in-memory value.
A Module instance is used to store all the information related to an LLVM module.
const DataLayout & getDataLayout() const
Get the data layout for the module's target platform.
uint64_t getReturnSaveOffset() const
getReturnSaveOffset - Return the previous frame offset to save the return address.
uint64_t getFramePointerSaveOffset() const
getFramePointerSaveOffset - Return the previous frame offset to save the frame pointer.
unsigned getLinkageSize() const
getLinkageSize - Return the size of the PowerPC ABI linkage area.
uint64_t getTOCSaveOffset() const
getTOCSaveOffset - Return the previous frame offset to save the TOC register – 64-bit SVR4 ABI only.
PPCFunctionInfo - This class is derived from MachineFunction private PowerPC target-specific informat...
void setVarArgsNumFPR(unsigned Num)
void setReturnAddrSaveIndex(int idx)
int getReturnAddrSaveIndex() const
unsigned getVarArgsNumFPR() const
int getFramePointerSaveIndex() const
void setVarArgsNumGPR(unsigned Num)
void appendParameterType(ParamType Type)
int getVarArgsFrameIndex() const
void setLRStoreRequired()
void setTailCallSPDelta(int size)
bool isLRStoreRequired() const
void setMinReservedArea(unsigned size)
unsigned getVarArgsNumGPR() const
unsigned getMinReservedArea() const
void setVarArgsStackOffset(int Offset)
void setVarArgsFrameIndex(int Index)
void addLiveInAttr(Register VReg, ISD::ArgFlagsTy Flags)
This function associates attributes for each live-in virtual register.
int getVarArgsStackOffset() const
void setFramePointerSaveIndex(int Idx)
static bool hasPCRelFlag(unsigned TF)
bool is32BitELFABI() const
unsigned descriptorTOCAnchorOffset() const
bool useSoftFloat() const
const PPCFrameLowering * getFrameLowering() const override
bool needsSwapsForVSXMemOps() const
bool isPPC64() const
isPPC64 - Return true if we are generating code for 64-bit pointer mode.
bool isUsingPCRelativeCalls() const
bool usesFunctionDescriptors() const
True if the ABI is descriptor based.
MCRegister getEnvironmentPointerRegister() const
const PPCInstrInfo * getInstrInfo() const override
unsigned getCPUDirective() const
getCPUDirective - Returns the -m directive specified for the cpu.
POPCNTDKind hasPOPCNTD() const
bool isLittleEndian() const
bool isTargetLinux() const
MCRegister getTOCPointerRegister() const
MCRegister getStackPointerRegister() const
bool is64BitELFABI() const
const PPCTargetMachine & getTargetMachine() const
bool isPredictableSelectIsExpensive() const
bool enableMachineScheduler() const override
Scheduling customization.
const PPCRegisterInfo * getRegisterInfo() const override
bool isGVIndirectSymbol(const GlobalValue *GV) const
True if the GV will be accessed via an indirect symbol.
unsigned descriptorEnvironmentPointerOffset() const
MachineBasicBlock * emitEHSjLjLongJmp(MachineInstr &MI, MachineBasicBlock *MBB) const
CCAssignFn * ccAssignFnForCall(CallingConv::ID CC, bool Return, bool IsVarArg) const
bool isTruncateFree(Type *Ty1, Type *Ty2) const override
isTruncateFree - Return true if it's free to truncate a value of type Ty1 to type Ty2.
Value * emitMaskedAtomicRMWIntrinsic(IRBuilderBase &Builder, AtomicRMWInst *AI, Value *AlignedAddr, Value *Incr, Value *Mask, Value *ShiftAmt, AtomicOrdering Ord) const override
Perform a masked atomicrmw using a target-specific intrinsic.
MachineBasicBlock * EmitInstrWithCustomInserter(MachineInstr &MI, MachineBasicBlock *MBB) const override
This method should be implemented by targets that mark instructions with the 'usesCustomInserter' fla...
bool isFPExtFree(EVT DestVT, EVT SrcVT) const override
Return true if an fpext operation is free (for instance, because single-precision floating-point numb...
PPC::AddrMode SelectForceXFormMode(SDValue N, SDValue &Disp, SDValue &Base, SelectionDAG &DAG) const
SelectForceXFormMode - Given the specified address, force it to be represented as an indexed [r+r] op...
Instruction * emitTrailingFence(IRBuilderBase &Builder, Instruction *Inst, AtomicOrdering Ord) const override
bool hasInlineStackProbe(const MachineFunction &MF) const override
MachineBasicBlock * emitEHSjLjSetJmp(MachineInstr &MI, MachineBasicBlock *MBB) const
const char * getTargetNodeName(unsigned Opcode) const override
getTargetNodeName() - This method returns the name of a target specific DAG node.
bool supportsTailCallFor(const CallBase *CB) const
bool isOffsetFoldingLegal(const GlobalAddressSDNode *GA) const override
Return true if folding a constant offset with the given GlobalAddress is legal.
MachineBasicBlock * emitProbedAlloca(MachineInstr &MI, MachineBasicBlock *MBB) const
bool isZExtFree(SDValue Val, EVT VT2) const override
Return true if zero-extending the specific node Val to type VT2 is free (either because it's implicit...
MachineBasicBlock * EmitPartwordAtomicBinary(MachineInstr &MI, MachineBasicBlock *MBB, bool is8bit, unsigned Opcode, unsigned CmpOpcode=0, unsigned CmpPred=0) const
SDValue getNegatedExpression(SDValue Op, SelectionDAG &DAG, bool LegalOps, bool OptForSize, NegatibleCost &Cost, unsigned Depth=0) const override
Return the newly negated expression if the cost is not expensive and set the cost in Cost to indicate...
bool SelectAddressRegImm(SDValue N, SDValue &Disp, SDValue &Base, SelectionDAG &DAG, MaybeAlign EncodingAlignment) const
SelectAddressRegImm - Returns true if the address N can be represented by a base register plus a sign...
bool getTgtMemIntrinsic(IntrinsicInfo &Info, const CallInst &I, MachineFunction &MF, unsigned Intrinsic) const override
Given an intrinsic, checks if on the target the intrinsic will need to map to a MemIntrinsicNode (tou...
SDValue expandVSXLoadForLE(SDNode *N, DAGCombinerInfo &DCI) const
bool splitValueIntoRegisterParts(SelectionDAG &DAG, const SDLoc &DL, SDValue Val, SDValue *Parts, unsigned NumParts, MVT PartVT, std::optional< CallingConv::ID > CC) const override
Target-specific splitting of values into parts that fit a register storing a legal type.
void LowerAsmOperandForConstraint(SDValue Op, StringRef Constraint, std::vector< SDValue > &Ops, SelectionDAG &DAG) const override
LowerAsmOperandForConstraint - Lower the specified operand into the Ops vector.
void ReplaceNodeResults(SDNode *N, SmallVectorImpl< SDValue > &Results, SelectionDAG &DAG) const override
ReplaceNodeResults - Replace the results of node with an illegal result type with new values built ou...
TargetLowering::AtomicExpansionKind shouldExpandAtomicRMWInIR(AtomicRMWInst *AI) const override
Returns how the IR-level AtomicExpand pass should expand the given AtomicRMW, if at all.
bool SelectAddressRegReg(SDValue N, SDValue &Base, SDValue &Index, SelectionDAG &DAG, MaybeAlign EncodingAlignment=std::nullopt) const
SelectAddressRegReg - Given the specified addressed, check to see if it can be more efficiently repre...
MachineBasicBlock * EmitAtomicBinary(MachineInstr &MI, MachineBasicBlock *MBB, unsigned AtomicSize, unsigned BinOpcode, unsigned CmpOpcode=0, unsigned CmpPred=0) const
SDValue BuildSDIVPow2(SDNode *N, const APInt &Divisor, SelectionDAG &DAG, SmallVectorImpl< SDNode * > &Created) const override
Targets may override this function to provide custom SDIV lowering for power-of-2 denominators.
void computeKnownBitsForTargetNode(const SDValue Op, KnownBits &Known, const APInt &DemandedElts, const SelectionDAG &DAG, unsigned Depth=0) const override
Determine which of the bits specified in Mask are known to be either zero or one and return them in t...
bool SelectAddressRegRegOnly(SDValue N, SDValue &Base, SDValue &Index, SelectionDAG &DAG) const
SelectAddressRegRegOnly - Given the specified addressed, force it to be represented as an indexed [r+...
bool useSoftFloat() const override
SDValue getPICJumpTableRelocBase(SDValue Table, SelectionDAG &DAG) const override
Returns relocation base for the given PIC jumptable.
void insertSSPDeclarations(Module &M) const override
Inserts necessary declarations for SSP (stack protection) purpose.
Value * emitMaskedAtomicCmpXchgIntrinsic(IRBuilderBase &Builder, AtomicCmpXchgInst *CI, Value *AlignedAddr, Value *CmpVal, Value *NewVal, Value *Mask, AtomicOrdering Ord) const override
Perform a masked cmpxchg using a target-specific intrinsic.
ConstraintWeight getSingleConstraintMatchWeight(AsmOperandInfo &info, const char *constraint) const override
Examine constraint string and operand type and determine a weight value.
uint64_t getByValTypeAlignment(Type *Ty, const DataLayout &DL) const override
getByValTypeAlignment - Return the desired alignment for ByVal aggregate function arguments in the ca...
bool enableAggressiveFMAFusion(EVT VT) const override
Return true if target always benefits from combining into FMA for a given value type.
Register getRegisterByName(const char *RegName, LLT VT, const MachineFunction &MF) const override
Return the register ID of the name passed in.
bool decomposeMulByConstant(LLVMContext &Context, EVT VT, SDValue C) const override
Return true if it is profitable to transform an integer multiplication-by-constant into simpler opera...
unsigned getJumpTableEncoding() const override
Return the entry encoding for a jump table in the current function.
bool isLegalAddressingMode(const DataLayout &DL, const AddrMode &AM, Type *Ty, unsigned AS, Instruction *I=nullptr) const override
isLegalAddressingMode - Return true if the addressing mode represented by AM is legal for this target...
bool preferIncOfAddToSubOfNot(EVT VT) const override
These two forms are equivalent: sub y, (xor x, -1) add (add x, 1), y The variant with two add's is IR...
bool shouldConvertConstantLoadToIntImm(const APInt &Imm, Type *Ty) const override
Returns true if it is beneficial to convert a load of a constant to just the constant itself.
const MCPhysReg * getScratchRegisters(CallingConv::ID CC) const override
Returns a 0 terminated array of registers that can be safely used as scratch registers.
bool getPreIndexedAddressParts(SDNode *N, SDValue &Base, SDValue &Offset, ISD::MemIndexedMode &AM, SelectionDAG &DAG) const override
getPreIndexedAddressParts - returns true by value, base pointer and offset pointer and addressing mod...
bool isProfitableToHoist(Instruction *I) const override
isProfitableToHoist - Check if it is profitable to hoist instruction I to its dominator block.
bool isFPImmLegal(const APFloat &Imm, EVT VT, bool ForCodeSize) const override
Returns true if the target can instruction select the specified FP immediate natively.
ConstraintType getConstraintType(StringRef Constraint) const override
getConstraintType - Given a constraint, return the type of constraint it is for this target.
const MCExpr * getPICJumpTableRelocBaseExpr(const MachineFunction *MF, unsigned JTI, MCContext &Ctx) const override
This returns the relocation base for the given PIC jumptable, the same as getPICJumpTableRelocBase,...
bool shallExtractConstSplatVectorElementToStore(Type *VectorTy, unsigned ElemSizeInBits, unsigned &Index) const override
Return true if the target shall perform extract vector element and store given that the vector is kno...
EVT getOptimalMemOpType(const MemOp &Op, const AttributeList &FuncAttributes) const override
It returns EVT::Other if the type should be determined using generic target-independent logic.
SDValue PerformDAGCombine(SDNode *N, DAGCombinerInfo &DCI) const override
This method will be invoked for all target nodes and for any target-independent nodes that the target...
SDValue expandVSXStoreForLE(SDNode *N, DAGCombinerInfo &DCI) const
void CollectTargetIntrinsicOperands(const CallInst &I, SmallVectorImpl< SDValue > &Ops, SelectionDAG &DAG) const override
bool useLoadStackGuardNode() const override
Override to support customized stack guard loading.
unsigned getStackProbeSize(const MachineFunction &MF) const
PPCTargetLowering(const PPCTargetMachine &TM, const PPCSubtarget &STI)
TargetLowering::AtomicExpansionKind shouldExpandAtomicCmpXchgInIR(AtomicCmpXchgInst *AI) const override
Returns how the given atomic cmpxchg should be expanded by the IR-level AtomicExpand pass.
bool isFMAFasterThanFMulAndFAdd(const MachineFunction &MF, EVT VT) const override
isFMAFasterThanFMulAndFAdd - Return true if an FMA operation is faster than a pair of fmul and fadd i...
bool allowsMisalignedMemoryAccesses(EVT VT, unsigned AddrSpace, Align Alignment=Align(1), MachineMemOperand::Flags Flags=MachineMemOperand::MONone, unsigned *Fast=nullptr) const override
Is unaligned memory access allowed for the given type, and is it fast relative to software emulation.
bool shouldExpandBuildVectorWithShuffles(EVT VT, unsigned DefinedValues) const override
bool SelectAddressRegImm34(SDValue N, SDValue &Disp, SDValue &Base, SelectionDAG &DAG) const
Similar to the 16-bit case but for instructions that take a 34-bit displacement field (prefixed loads...
std::pair< unsigned, const TargetRegisterClass * > getRegForInlineAsmConstraint(const TargetRegisterInfo *TRI, StringRef Constraint, MVT VT) const override
Given a physical register constraint (e.g.
Register getExceptionSelectorRegister(const Constant *PersonalityFn) const override
If a physical register, this returns the register that receives the exception typeid on entry to a la...
bool isJumpTableRelative() const override
Register getExceptionPointerRegister(const Constant *PersonalityFn) const override
If a physical register, this returns the register that receives the exception address on entry to an ...
SDValue LowerOperation(SDValue Op, SelectionDAG &DAG) const override
LowerOperation - Provide custom lowering hooks for some operations.
PPC::AddrMode SelectOptimalAddrMode(const SDNode *Parent, SDValue N, SDValue &Disp, SDValue &Base, SelectionDAG &DAG, MaybeAlign Align) const
SelectOptimalAddrMode - Based on a node N and it's Parent (a MemSDNode), compute the address flags of...
Value * getSDagStackGuard(const Module &M) const override
Return the variable that's previously inserted by insertSSPDeclarations, if any, otherwise return nul...
bool SelectAddressPCRel(SDValue N, SDValue &Base) const
SelectAddressPCRel - Represent the specified address as pc relative to be represented as [pc+imm].
EVT getSetCCResultType(const DataLayout &DL, LLVMContext &Context, EVT VT) const override
getSetCCResultType - Return the ISD::SETCC ValueType
bool SelectAddressEVXRegReg(SDValue N, SDValue &Base, SDValue &Index, SelectionDAG &DAG) const
SelectAddressEVXRegReg - Given the specified addressed, check to see if it can be more efficiently re...
bool isLegalICmpImmediate(int64_t Imm) const override
isLegalICmpImmediate - Return true if the specified immediate is legal icmp immediate,...
bool isAccessedAsGotIndirect(SDValue N) const
Align getPrefLoopAlignment(MachineLoop *ML) const override
Return the preferred loop alignment.
FastISel * createFastISel(FunctionLoweringInfo &FuncInfo, const TargetLibraryInfo *LibInfo) const override
createFastISel - This method returns a target-specific FastISel object, or null if the target does no...
bool shouldInlineQuadwordAtomics() const
Instruction * emitLeadingFence(IRBuilderBase &Builder, Instruction *Inst, AtomicOrdering Ord) const override
Inserts in the IR a target-specific intrinsic specifying a fence.
bool isLegalAddImmediate(int64_t Imm) const override
isLegalAddImmediate - Return true if the specified immediate is legal add immediate,...
Common code between 32-bit and 64-bit PowerPC targets.
static PointerType * getUnqual(Type *ElementType)
This constructs a pointer to an object of the specified type in the default address space (address sp...
Wrapper class representing virtual and physical registers.
constexpr bool isVirtual() const
Return true if the specified register number is in the virtual register namespace.
Wrapper class for IR location info (IR ordering and DebugLoc) to be passed into SDNode creation funct...
This class provides iterator support for SDUse operands that use a specific SDNode.
Represents one node in the SelectionDAG.
ArrayRef< SDUse > ops() const
void dump() const
Dump this node, for debugging.
unsigned getOpcode() const
Return the SelectionDAG opcode value for this node.
bool hasOneUse() const
Return true if there is exactly one use of this node.
iterator_range< use_iterator > uses()
SDNodeFlags getFlags() const
uint64_t getAsZExtVal() const
Helper method returns the zero-extended integer value of a ConstantSDNode.
unsigned getNumValues() const
Return the number of values defined/returned by this operator.
const SDValue & getOperand(unsigned Num) const
uint64_t getConstantOperandVal(unsigned Num) const
Helper method returns the integer value of a ConstantSDNode operand.
use_iterator use_begin() const
Provide iteration support to walk over all uses of an SDNode.
EVT getValueType(unsigned ResNo) const
Return the type of a specified result.
bool hasNUsesOfValue(unsigned NUses, unsigned Value) const
Return true if there are exactly NUSES uses of the indicated value.
op_iterator op_end() const
op_iterator op_begin() const
static use_iterator use_end()
Represents a use of a SDNode.
Unlike LLVM values, Selection DAG nodes may return multiple values as the result of a computation.
SDNode * getNode() const
get the SDNode which holds the desired result
bool hasOneUse() const
Return true if there is exactly one node using value ResNo of Node.
SDValue getValue(unsigned R) const
EVT getValueType() const
Return the ValueType of the referenced return value.
TypeSize getValueSizeInBits() const
Returns the size of the value in bits.
const SDValue & getOperand(unsigned i) const
uint64_t getConstantOperandVal(unsigned i) const
MVT getSimpleValueType() const
Return the simple ValueType of the referenced return value.
unsigned getOpcode() const
unsigned getNumOperands() const
static SectionKind getMetadata()
This is used to represent a portion of an LLVM function in a low-level Data Dependence DAG representa...
SDValue getExtLoad(ISD::LoadExtType ExtType, const SDLoc &dl, EVT VT, SDValue Chain, SDValue Ptr, MachinePointerInfo PtrInfo, EVT MemVT, MaybeAlign Alignment=MaybeAlign(), MachineMemOperand::Flags MMOFlags=MachineMemOperand::MONone, const AAMDNodes &AAInfo=AAMDNodes())
SDValue getTargetGlobalAddress(const GlobalValue *GV, const SDLoc &DL, EVT VT, int64_t offset=0, unsigned TargetFlags=0)
SDValue getSelect(const SDLoc &DL, EVT VT, SDValue Cond, SDValue LHS, SDValue RHS)
Helper function to make it easier to build Select's if you just have operands and don't want to check...
SDValue getStackArgumentTokenFactor(SDValue Chain)
Compute a TokenFactor to force all the incoming stack arguments to be loaded from the stack.
const TargetSubtargetInfo & getSubtarget() const
SDValue getMergeValues(ArrayRef< SDValue > Ops, const SDLoc &dl)
Create a MERGE_VALUES node from the given operands.
SDVTList getVTList(EVT VT)
Return an SDVTList that represents the list of values specified.
MachineSDNode * getMachineNode(unsigned Opcode, const SDLoc &dl, EVT VT)
These are used for target selectors to create a new node with specified return type(s),...
SDValue makeEquivalentMemoryOrdering(SDValue OldChain, SDValue NewMemOpChain)
If an existing load has uses of its chain, create a token factor node with that chain and the new mem...
SDValue getSetCC(const SDLoc &DL, EVT VT, SDValue LHS, SDValue RHS, ISD::CondCode Cond, SDValue Chain=SDValue(), bool IsSignaling=false)
Helper function to make it easier to build SetCC's if you just have an ISD::CondCode instead of an SD...
SDValue getConstantFP(double Val, const SDLoc &DL, EVT VT, bool isTarget=false)
Create a ConstantFPSDNode wrapping a constant value.
SDValue getLoad(EVT VT, const SDLoc &dl, SDValue Chain, SDValue Ptr, MachinePointerInfo PtrInfo, MaybeAlign Alignment=MaybeAlign(), MachineMemOperand::Flags MMOFlags=MachineMemOperand::MONone, const AAMDNodes &AAInfo=AAMDNodes(), const MDNode *Ranges=nullptr)
Loads are not normal binary operators: their result type is not determined by their operands,...
Align getEVTAlign(EVT MemoryVT) const
Compute the default alignment value for the given type.
void addNoMergeSiteInfo(const SDNode *Node, bool NoMerge)
Set NoMergeSiteInfo to be associated with Node if NoMerge is true.
SDValue getNOT(const SDLoc &DL, SDValue Val, EVT VT)
Create a bitwise NOT operation as (XOR Val, -1).
const TargetLowering & getTargetLoweringInfo() const
static constexpr unsigned MaxRecursionDepth
SDValue getTargetJumpTable(int JTI, EVT VT, unsigned TargetFlags=0)
SDValue getUNDEF(EVT VT)
Return an UNDEF node. UNDEF does not have a useful SDLoc.
SDValue getCALLSEQ_END(SDValue Chain, SDValue Op1, SDValue Op2, SDValue InGlue, const SDLoc &DL)
Return a new CALLSEQ_END node, which always must have a glue result (to ensure it's not CSE'd).
SDValue getBuildVector(EVT VT, const SDLoc &DL, ArrayRef< SDValue > Ops)
Return an ISD::BUILD_VECTOR node.
SDValue getMemcpy(SDValue Chain, const SDLoc &dl, SDValue Dst, SDValue Src, SDValue Size, Align Alignment, bool isVol, bool AlwaysInline, bool isTailCall, MachinePointerInfo DstPtrInfo, MachinePointerInfo SrcPtrInfo, const AAMDNodes &AAInfo=AAMDNodes(), AAResults *AA=nullptr)
bool isSplatValue(SDValue V, const APInt &DemandedElts, APInt &UndefElts, unsigned Depth=0) const
Test whether V has a splatted value for all the demanded elements.
SDValue getBitcast(EVT VT, SDValue V)
Return a bitcast using the SDLoc of the value operand, and casting to the provided type.
const DataLayout & getDataLayout() const
SDValue getTargetFrameIndex(int FI, EVT VT)
SDValue getTokenFactor(const SDLoc &DL, SmallVectorImpl< SDValue > &Vals)
Creates a new TokenFactor containing Vals.
bool areNonVolatileConsecutiveLoads(LoadSDNode *LD, LoadSDNode *Base, unsigned Bytes, int Dist) const
Return true if loads are next to each other and can be merged.
SDValue getConstant(uint64_t Val, const SDLoc &DL, EVT VT, bool isTarget=false, bool isOpaque=false)
Create a ConstantSDNode wrapping a constant value.
SDValue getTruncStore(SDValue Chain, const SDLoc &dl, SDValue Val, SDValue Ptr, MachinePointerInfo PtrInfo, EVT SVT, Align Alignment, MachineMemOperand::Flags MMOFlags=MachineMemOperand::MONone, const AAMDNodes &AAInfo=AAMDNodes())
SDValue getMDNode(const MDNode *MD)
Return an MDNodeSDNode which holds an MDNode.
void ReplaceAllUsesWith(SDValue From, SDValue To)
Modify anything using 'From' to use 'To' instead.
SDValue getCommutedVectorShuffle(const ShuffleVectorSDNode &SV)
Returns an ISD::VECTOR_SHUFFLE node semantically equivalent to the shuffle node in input but with swa...
SDValue getStore(SDValue Chain, const SDLoc &dl, SDValue Val, SDValue Ptr, MachinePointerInfo PtrInfo, Align Alignment, MachineMemOperand::Flags MMOFlags=MachineMemOperand::MONone, const AAMDNodes &AAInfo=AAMDNodes())
Helper function to build ISD::STORE nodes.
SDValue getCALLSEQ_START(SDValue Chain, uint64_t InSize, uint64_t OutSize, const SDLoc &DL)
Return a new CALLSEQ_START node, that starts new call frame, in which InSize bytes are set up inside ...
SDValue getRegister(unsigned Reg, EVT VT)
SDValue getSExtOrTrunc(SDValue Op, const SDLoc &DL, EVT VT)
Convert Op, which must be of integer type, to the integer type VT, by either sign-extending or trunca...
SDValue getBoolExtOrTrunc(SDValue Op, const SDLoc &SL, EVT VT, EVT OpVT)
Convert Op, which must be of integer type, to the integer type VT, by using an extension appropriate ...
SDValue getExternalSymbol(const char *Sym, EVT VT)
const TargetMachine & getTarget() const
SDValue getAnyExtOrTrunc(SDValue Op, const SDLoc &DL, EVT VT)
Convert Op, which must be of integer type, to the integer type VT, by either any-extending or truncat...
SDValue getCopyToReg(SDValue Chain, const SDLoc &dl, unsigned Reg, SDValue N)
SDValue getSelectCC(const SDLoc &DL, SDValue LHS, SDValue RHS, SDValue True, SDValue False, ISD::CondCode Cond)
Helper function to make it easier to build SelectCC's if you just have an ISD::CondCode instead of an...
SDValue getMemIntrinsicNode(unsigned Opcode, const SDLoc &dl, SDVTList VTList, ArrayRef< SDValue > Ops, EVT MemVT, MachinePointerInfo PtrInfo, Align Alignment, MachineMemOperand::Flags Flags=MachineMemOperand::MOLoad|MachineMemOperand::MOStore, uint64_t Size=0, const AAMDNodes &AAInfo=AAMDNodes())
Creates a MemIntrinsicNode that may produce a result and takes a list of operands.
SDValue getIntPtrConstant(uint64_t Val, const SDLoc &DL, bool isTarget=false)
SDValue getValueType(EVT)
SDValue getNode(unsigned Opcode, const SDLoc &DL, EVT VT, ArrayRef< SDUse > Ops)
Gets or creates the specified node.
SDValue getTargetConstant(uint64_t Val, const SDLoc &DL, EVT VT, bool isOpaque=false)
unsigned ComputeNumSignBits(SDValue Op, unsigned Depth=0) const
Return the number of times the sign bit of the register is replicated into the other bits.
SDValue getBoolConstant(bool V, const SDLoc &DL, EVT VT, EVT OpVT)
Create a true or false constant of type VT using the target's BooleanContent for type OpVT.
SDValue getTargetBlockAddress(const BlockAddress *BA, EVT VT, int64_t Offset=0, unsigned TargetFlags=0)
bool isBaseWithConstantOffset(SDValue Op) const
Return true if the specified operand is an ISD::ADD with a ConstantSDNode on the right-hand side,...
SDValue getVectorIdxConstant(uint64_t Val, const SDLoc &DL, bool isTarget=false)
void ReplaceAllUsesOfValueWith(SDValue From, SDValue To)
Replace any uses of From with To, leaving uses of other values produced by From.getNode() alone.
MachineFunction & getMachineFunction() const
SDValue getCopyFromReg(SDValue Chain, const SDLoc &dl, unsigned Reg, EVT VT)
SDValue getSplatBuildVector(EVT VT, const SDLoc &DL, SDValue Op)
Return a splat ISD::BUILD_VECTOR node, consisting of Op splatted to all elements.
SDValue getFrameIndex(int FI, EVT VT, bool isTarget=false)
KnownBits computeKnownBits(SDValue Op, unsigned Depth=0) const
Determine which bits of Op are known to be either zero or one and return them in Known.
SDValue getRegisterMask(const uint32_t *RegMask)
SDValue getZExtOrTrunc(SDValue Op, const SDLoc &DL, EVT VT)
Convert Op, which must be of integer type, to the integer type VT, by either zero-extending or trunca...
SDValue getCondCode(ISD::CondCode Cond)
bool MaskedValueIsZero(SDValue Op, const APInt &Mask, unsigned Depth=0) const
Return true if 'Op & Mask' is known to be zero.
SDValue getObjectPtrOffset(const SDLoc &SL, SDValue Ptr, TypeSize Offset)
Create an add instruction with appropriate flags when used for addressing some offset of an object.
LLVMContext * getContext() const
SDValue getTargetExternalSymbol(const char *Sym, EVT VT, unsigned TargetFlags=0)
SDValue getMCSymbol(MCSymbol *Sym, EVT VT)
SDValue CreateStackTemporary(TypeSize Bytes, Align Alignment)
Create a stack temporary based on the size in bytes and the alignment.
SDNode * UpdateNodeOperands(SDNode *N, SDValue Op)
Mutate the specified node in-place to have the specified operands.
SDValue getTargetConstantPool(const Constant *C, EVT VT, MaybeAlign Align=std::nullopt, int Offset=0, unsigned TargetFlags=0)
SDValue getEntryNode() const
Return the token chain corresponding to the entry of the function.
std::pair< SDValue, SDValue > SplitScalar(const SDValue &N, const SDLoc &DL, const EVT &LoVT, const EVT &HiVT)
Split the scalar node with EXTRACT_ELEMENT using the provided VTs and return the low/high part.
SDValue getVectorShuffle(EVT VT, const SDLoc &dl, SDValue N1, SDValue N2, ArrayRef< int > Mask)
Return an ISD::VECTOR_SHUFFLE node.
This SDNode is used to implement the code generator support for the llvm IR shufflevector instruction...
int getMaskElt(unsigned Idx) const
ArrayRef< int > getMask() const
size_type count(ConstPtrType Ptr) const
count - Return 1 if the specified pointer is in the set, 0 otherwise.
std::pair< iterator, bool > insert(PtrType Ptr)
Inserts Ptr if and only if there is no element in the container equal to Ptr.
SmallPtrSet - This class implements a set which is optimized for holding SmallSize or less elements.
SmallSet - This maintains a set of unique values, optimizing for the case when the set is small (less...
size_type count(const T &V) const
count - Return 1 if the element is in the set, 0 otherwise.
std::pair< const_iterator, bool > insert(const T &V)
insert - Insert an element into the set if it isn't already there.
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
void push_back(const T &Elt)
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
StackOffset holds a fixed and a scalable offset in bytes.
This class is used to represent ISD::STORE nodes.
const SDValue & getBasePtr() const
const SDValue & getValue() const
StringRef - Represent a constant reference to a string, i.e.
constexpr size_t size() const
size - Get the string size.
constexpr const char * data() const
data - Get a pointer to the start of the string (which may not be null terminated).
A switch()-like statement whose cases are string literals.
StringSwitch & Case(StringLiteral S, T Value)
Class to represent struct types.
Information about stack frame layout on the target.
unsigned getStackAlignment() const
getStackAlignment - This method returns the number of bytes to which the stack pointer must be aligne...
TargetInstrInfo - Interface to description of machine instruction set.
Provides information about what library functions are available for the current target.
void setBooleanVectorContents(BooleanContent Ty)
Specify how the target extends the result of a vector boolean value from a vector of i1 to a wider ty...
void setOperationAction(unsigned Op, MVT VT, LegalizeAction Action)
Indicate that the specified operation does not work with the specified type and indicate what to do a...
virtual bool shouldSignExtendTypeInLibCall(EVT Type, bool IsSigned) const
Returns true if arguments should be sign-extended in lib calls.
bool PredictableSelectIsExpensive
Tells the code generator that select is more expensive than a branch if the branch is usually predict...
EVT getValueType(const DataLayout &DL, Type *Ty, bool AllowUnknown=false) const
Return the EVT corresponding to this LLVM type.
virtual bool shouldExpandBuildVectorWithShuffles(EVT, unsigned DefinedValues) const
unsigned MaxStoresPerMemcpyOptSize
Likewise for functions with the OptSize attribute.
MachineBasicBlock * emitPatchPoint(MachineInstr &MI, MachineBasicBlock *MBB) const
Replace/modify any TargetFrameIndex operands with a targte-dependent sequence of memory operands that...
virtual const TargetRegisterClass * getRegClassFor(MVT VT, bool isDivergent=false) const
Return the register class that should be used for the specified value type.
void setMinStackArgumentAlignment(Align Alignment)
Set the minimum stack alignment of an argument.
virtual MVT getVectorIdxTy(const DataLayout &DL) const
Returns the type to be used for the index operand of: ISD::INSERT_VECTOR_ELT, ISD::EXTRACT_VECTOR_ELT...
const TargetMachine & getTargetMachine() const
unsigned MaxLoadsPerMemcmp
Specify maximum number of load instructions per memcmp call.
virtual bool isZExtFree(Type *FromTy, Type *ToTy) const
Return true if any actual instruction that defines a value of type FromTy implicitly zero-extends the...
virtual Value * getSDagStackGuard(const Module &M) const
Return the variable that's previously inserted by insertSSPDeclarations, if any, otherwise return nul...
void setIndexedLoadAction(ArrayRef< unsigned > IdxModes, MVT VT, LegalizeAction Action)
Indicate that the specified indexed load does or does not work with the specified type and indicate w...
void setPrefLoopAlignment(Align Alignment)
Set the target's preferred loop alignment.
void setMaxAtomicSizeInBitsSupported(unsigned SizeInBits)
Set the maximum atomic operation size supported by the backend.
Sched::Preference getSchedulingPreference() const
Return target scheduling preference.
void setMinFunctionAlignment(Align Alignment)
Set the target's minimum function alignment.
bool isOperationCustom(unsigned Op, EVT VT) const
Return true if the operation uses custom lowering, regardless of whether the type is legal or not.
unsigned MaxStoresPerMemsetOptSize
Likewise for functions with the OptSize attribute.
bool hasBigEndianPartOrdering(EVT VT, const DataLayout &DL) const
When splitting a value of the specified type into parts, does the Lo or Hi part come first?...
void setBooleanContents(BooleanContent Ty)
Specify how the target extends the result of integer and floating point boolean values from i1 to a w...
unsigned MaxStoresPerMemmove
Specify maximum number of store instructions per memmove call.
virtual Align getPrefLoopAlignment(MachineLoop *ML=nullptr) const
Return the preferred loop alignment.
void computeRegisterProperties(const TargetRegisterInfo *TRI)
Once all of the register classes are added, this allows us to compute derived properties we expose.
EVT getShiftAmountTy(EVT LHSTy, const DataLayout &DL, bool LegalTypes=true) const
Returns the type for the shift amount of a shift opcode.
unsigned MaxStoresPerMemmoveOptSize
Likewise for functions with the OptSize attribute.
void addRegisterClass(MVT VT, const TargetRegisterClass *RC)
Add the specified register class as an available regclass for the specified value type.
bool isTypeLegal(EVT VT) const
Return true if the target has native support for the specified value type.
void setIndexedStoreAction(ArrayRef< unsigned > IdxModes, MVT VT, LegalizeAction Action)
Indicate that the specified indexed store does or does not work with the specified type and indicate ...
virtual bool isJumpTableRelative() const
virtual MVT getPointerTy(const DataLayout &DL, uint32_t AS=0) const
Return the pointer type for the given address space, defaults to the pointer type from the data layou...
void setLibcallName(RTLIB::Libcall Call, const char *Name)
Rename the default libcall routine name for the specified libcall.
void setPrefFunctionAlignment(Align Alignment)
Set the target's preferred function alignment.
bool isOperationLegal(unsigned Op, EVT VT) const
Return true if the specified operation is legal on this target.
virtual AtomicExpansionKind shouldExpandAtomicCmpXchgInIR(AtomicCmpXchgInst *AI) const
Returns how the given atomic cmpxchg should be expanded by the IR-level AtomicExpand pass.
unsigned MaxStoresPerMemset
Specify maximum number of store instructions per memset call.
void setMinimumJumpTableEntries(unsigned Val)
Indicate the minimum number of blocks to generate jump tables.
void setTruncStoreAction(MVT ValVT, MVT MemVT, LegalizeAction Action)
Indicate that the specified truncating store does not work with the specified type and indicate what ...
@ ZeroOrOneBooleanContent
@ ZeroOrNegativeOneBooleanContent
bool isOperationLegalOrCustom(unsigned Op, EVT VT, bool LegalOnly=false) const
Return true if the specified operation is legal on this target or can be made legal with custom lower...
unsigned MaxLoadsPerMemcmpOptSize
Likewise for functions with the OptSize attribute.
void setStackPointerRegisterToSaveRestore(Register R)
If set to a physical register, this specifies the register that llvm.savestack/llvm....
void AddPromotedToType(unsigned Opc, MVT OrigVT, MVT DestVT)
If Opc/OrigVT is specified as being promoted, the promotion code defaults to trying a larger integer/...
AtomicExpansionKind
Enum that specifies what an atomic load/AtomicRMWInst is expanded to, if at all.
void setCondCodeAction(ArrayRef< ISD::CondCode > CCs, MVT VT, LegalizeAction Action)
Indicate that the specified condition code is or isn't supported on the target and indicate what to d...
void setTargetDAGCombine(ArrayRef< ISD::NodeType > NTs)
Targets should invoke this method for each target independent node that they want to provide a custom...
virtual AtomicExpansionKind shouldExpandAtomicRMWInIR(AtomicRMWInst *RMW) const
Returns how the IR-level AtomicExpand pass should expand the given AtomicRMW, if at all.
void setLoadExtAction(unsigned ExtType, MVT ValVT, MVT MemVT, LegalizeAction Action)
Indicate that the specified load with extension does not work with the specified type and indicate wh...
NegatibleCost
Enum that specifies when a float negation is beneficial.
std::vector< ArgListEntry > ArgListTy
void setHasMultipleConditionRegisters(bool hasManyRegs=true)
Tells the code generator that the target has multiple (allocatable) condition registers that can be u...
unsigned MaxStoresPerMemcpy
Specify maximum number of store instructions per memcpy call.
void setSchedulingPreference(Sched::Preference Pref)
Specify the target scheduling preference.
virtual void insertSSPDeclarations(Module &M) const
Inserts necessary declarations for SSP (stack protection) purpose.
void setJumpIsExpensive(bool isExpensive=true)
Tells the code generator not to expand logic operations on comparison predicates into separate sequen...
virtual MCSymbol * getFunctionEntryPointSymbol(const GlobalValue *Func, const TargetMachine &TM) const
If supported, return the function entry point symbol.
This class defines information used to lower LLVM code to legal SelectionDAG operators that the targe...
virtual const MCExpr * getPICJumpTableRelocBaseExpr(const MachineFunction *MF, unsigned JTI, MCContext &Ctx) const
This returns the relocation base for the given PIC jumptable, the same as getPICJumpTableRelocBase,...
SDValue lowerCmpEqZeroToCtlzSrl(SDValue Op, SelectionDAG &DAG) const
virtual bool useLoadStackGuardNode() const
If this function returns true, SelectionDAGBuilder emits a LOAD_STACK_GUARD node when it is lowering ...
void softenSetCCOperands(SelectionDAG &DAG, EVT VT, SDValue &NewLHS, SDValue &NewRHS, ISD::CondCode &CCCode, const SDLoc &DL, const SDValue OldLHS, const SDValue OldRHS) const
Soften the operands of a comparison.
std::pair< SDValue, SDValue > makeLibCall(SelectionDAG &DAG, RTLIB::Libcall LC, EVT RetVT, ArrayRef< SDValue > Ops, MakeLibCallOptions CallOptions, const SDLoc &dl, SDValue Chain=SDValue()) const
Returns a pair of (return value, chain).
SDValue getCheaperNegatedExpression(SDValue Op, SelectionDAG &DAG, bool LegalOps, bool OptForSize, unsigned Depth=0) const
This is the helper function to return the newly negated expression only when the cost is cheaper.
virtual ConstraintType getConstraintType(StringRef Constraint) const
Given a constraint, return the type of constraint it is for this target.
virtual SDValue LowerToTLSEmulatedModel(const GlobalAddressSDNode *GA, SelectionDAG &DAG) const
Lower TLS global address SDNode for target independent emulated TLS model.
std::pair< SDValue, SDValue > LowerCallTo(CallLoweringInfo &CLI) const
This function lowers an abstract call to a function into an actual call.
bool isPositionIndependent() const
virtual SDValue getNegatedExpression(SDValue Op, SelectionDAG &DAG, bool LegalOps, bool OptForSize, NegatibleCost &Cost, unsigned Depth=0) const
Return the newly negated expression if the cost is not expensive and set the cost in Cost to indicate...
virtual ConstraintWeight getSingleConstraintMatchWeight(AsmOperandInfo &info, const char *constraint) const
Examine constraint string and operand type and determine a weight value.
virtual SDValue getSqrtInputTest(SDValue Operand, SelectionDAG &DAG, const DenormalMode &Mode) const
Return a target-dependent comparison result if the input operand is suitable for use with a square ro...
virtual SDValue getPICJumpTableRelocBase(SDValue Table, SelectionDAG &DAG) const
Returns relocation base for the given PIC jumptable.
virtual std::pair< unsigned, const TargetRegisterClass * > getRegForInlineAsmConstraint(const TargetRegisterInfo *TRI, StringRef Constraint, MVT VT) const
Given a physical register constraint (e.g.
bool verifyReturnAddressArgumentIsConstant(SDValue Op, SelectionDAG &DAG) const
bool isInTailCallPosition(SelectionDAG &DAG, SDNode *Node, SDValue &Chain) const
Check whether a given call node is in tail position within its function.
virtual SDValue getSqrtResultForDenormInput(SDValue Operand, SelectionDAG &DAG) const
Return a target-dependent result if the input operand is not suitable for use with a square root esti...
virtual void LowerAsmOperandForConstraint(SDValue Op, StringRef Constraint, std::vector< SDValue > &Ops, SelectionDAG &DAG) const
Lower the specified operand into the Ops vector.
virtual bool isGAPlusOffset(SDNode *N, const GlobalValue *&GA, int64_t &Offset) const
Returns true (and the GlobalValue and the offset) if the node is a GlobalAddress + offset.
virtual unsigned getJumpTableEncoding() const
Return the entry encoding for a jump table in the current function.
Primary interface to the complete machine description for the target machine.
TLSModel::Model getTLSModel(const GlobalValue *GV) const
Returns the TLS model which should be used for the given global variable.
bool useEmulatedTLS() const
Returns true if this target uses emulated TLS.
Reloc::Model getRelocationModel() const
Returns the code generation relocation model.
bool shouldAssumeDSOLocal(const Module &M, const GlobalValue *GV) const
CodeModel::Model getCodeModel() const
Returns the code model.
unsigned UnsafeFPMath
UnsafeFPMath - This flag is enabled when the -enable-unsafe-fp-math flag is specified on the command ...
unsigned NoInfsFPMath
NoInfsFPMath - This flag is enabled when the -enable-no-infs-fp-math flag is specified on the command...
unsigned PPCGenScalarMASSEntries
Enables scalar MASS conversions.
unsigned NoNaNsFPMath
NoNaNsFPMath - This flag is enabled when the -enable-no-nans-fp-math flag is specified on the command...
unsigned GuaranteedTailCallOpt
GuaranteedTailCallOpt - This flag is enabled when -tailcallopt is specified on the commandline.
TargetRegisterInfo base class - We assume that the target defines a static array of TargetRegisterDes...
Twine - A lightweight data structure for efficiently representing the concatenation of temporary valu...
static constexpr TypeSize getFixed(ScalarTy ExactSize)
The instances of the Type class are immutable: once they are created, they are never changed.
bool isVectorTy() const
True if this is an instance of VectorType.
bool isFloatTy() const
Return true if this is 'float', a 32-bit IEEE fp type.
bool isEmptyTy() const
Return true if this type is empty, that is, it has no elements or all of its elements are empty.
@ FloatTyID
32-bit floating point type
@ DoubleTyID
64-bit floating point type
@ FP128TyID
128-bit floating point type (112-bit significand)
static Type * getVoidTy(LLVMContext &C)
bool isSized(SmallPtrSetImpl< Type * > *Visited=nullptr) const
Return true if it makes sense to take the size of this type.
bool isDoubleTy() const
Return true if this is 'double', a 64-bit IEEE fp type.
bool isFunctionTy() const
True if this is an instance of FunctionType.
static IntegerType * getInt64Ty(LLVMContext &C)
bool isIntegerTy() const
True if this is an instance of IntegerType.
TypeID getTypeID() const
Return the type id for the type.
TypeSize getPrimitiveSizeInBits() const LLVM_READONLY
Return the basic size of this type if it is a primitive type.
Type * getScalarType() const
If this is a vector type, return the element type, otherwise return 'this'.
A Use represents the edge between a Value definition and its users.
Value * getOperand(unsigned i) const
unsigned getNumOperands() const
LLVM Value Representation.
Type * getType() const
All values are typed, get the type of this value.
bool hasOneUse() const
Return true if there is exactly one use of this value.
self_iterator getIterator()
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
constexpr char Args[]
Key for Kernel::Metadata::mArgs.
constexpr std::underlying_type_t< E > Mask()
Get a bitmask with 1s in all places up to the high-order bit of E's largest value.
@ Cold
Attempts to make code in the caller as efficient as possible under the assumption that the call is no...
@ Fast
Attempts to make calls as fast as possible (e.g.
@ C
The default llvm calling convention, compatible with C.
bool isNON_EXTLoad(const SDNode *N)
Returns true if the specified node is a non-extending load.
NodeType
ISD::NodeType enum - This enum defines the target-independent operators for a SelectionDAG.
@ SETCC
SetCC operator - This evaluates to a true value iff the condition is true.
@ MERGE_VALUES
MERGE_VALUES - This node takes multiple discrete operands and returns them all as its individual resu...
@ STACKRESTORE
STACKRESTORE has two operands, an input chain and a pointer to restore to it returns an output chain.
@ STACKSAVE
STACKSAVE - STACKSAVE has one operand, an input chain.
@ STRICT_FSETCC
STRICT_FSETCC/STRICT_FSETCCS - Constrained versions of SETCC, used for floating-point operands only.
@ DELETED_NODE
DELETED_NODE - This is an illegal value that is used to catch errors.
@ EH_SJLJ_LONGJMP
OUTCHAIN = EH_SJLJ_LONGJMP(INCHAIN, buffer) This corresponds to the eh.sjlj.longjmp intrinsic.
@ SMUL_LOHI
SMUL_LOHI/UMUL_LOHI - Multiply two integers of type iN, producing a signed/unsigned value of type i[2...
@ BSWAP
Byte Swap and Counting operators.
@ VAEND
VAEND, VASTART - VAEND and VASTART have three operands: an input chain, pointer, and a SRCVALUE.
@ ATOMIC_STORE
OUTCHAIN = ATOMIC_STORE(INCHAIN, ptr, val) This corresponds to "store atomic" instruction.
@ ADDC
Carry-setting nodes for multiple precision addition and subtraction.
@ ADD
Simple integer binary arithmetic operators.
@ LOAD
LOAD and STORE have token chains as their first operand, then the same operands as an LLVM load/store...
@ ANY_EXTEND
ANY_EXTEND - Used for integer types. The high bits are undefined.
@ FMA
FMA - Perform a * b + c with no intermediate rounding step.
@ INTRINSIC_VOID
OUTCHAIN = INTRINSIC_VOID(INCHAIN, INTRINSICID, arg1, arg2, ...) This node represents a target intrin...
@ SINT_TO_FP
[SU]INT_TO_FP - These operators convert integers (whose interpreted sign depends on the first letter)...
@ CONCAT_VECTORS
CONCAT_VECTORS(VECTOR0, VECTOR1, ...) - Given a number of values of vector type with the same length ...
@ FADD
Simple binary floating point operators.
@ ABS
ABS - Determine the unsigned absolute value of a signed integer value of the same bitwidth.
@ SDIVREM
SDIVREM/UDIVREM - Divide two integers and produce both a quotient and remainder result.
@ FP16_TO_FP
FP16_TO_FP, FP_TO_FP16 - These operators are used to perform promotions and truncation for half-preci...
@ BITCAST
BITCAST - This operator converts between integer, vector and FP values, as if the value was stored to...
@ BUILD_PAIR
BUILD_PAIR - This is the opposite of EXTRACT_ELEMENT in some ways.
@ INIT_TRAMPOLINE
INIT_TRAMPOLINE - This corresponds to the init_trampoline intrinsic.
@ FLDEXP
FLDEXP - ldexp, inspired by libm (op0 * 2**op1).
@ STRICT_FSQRT
Constrained versions of libm-equivalent floating point intrinsics.
@ SIGN_EXTEND
Conversion operators.
@ SCALAR_TO_VECTOR
SCALAR_TO_VECTOR(VAL) - This represents the operation of loading a scalar value into element 0 of the...
@ BR
Control flow instructions. These all have token chains.
@ PREFETCH
PREFETCH - This corresponds to a prefetch intrinsic.
@ FSINCOS
FSINCOS - Compute both fsin and fcos as a single operation.
@ FNEG
Perform various unary floating-point operations inspired by libm.
@ BR_CC
BR_CC - Conditional branch.
@ BR_JT
BR_JT - Jumptable branch.
@ IS_FPCLASS
Performs a check of floating point class property, defined by IEEE-754.
@ SSUBSAT
RESULT = [US]SUBSAT(LHS, RHS) - Perform saturation subtraction on 2 integers with the same bit width ...
@ SELECT
Select(COND, TRUEVAL, FALSEVAL).
@ ATOMIC_LOAD
Val, OUTCHAIN = ATOMIC_LOAD(INCHAIN, ptr) This corresponds to "load atomic" instruction.
@ EXTRACT_ELEMENT
EXTRACT_ELEMENT - This is used to get the lower or upper (determined by a Constant,...
@ VACOPY
VACOPY - VACOPY has 5 operands: an input chain, a destination pointer, a source pointer,...
@ TargetGlobalAddress
TargetGlobalAddress - Like GlobalAddress, but the DAG does no folding or anything else with this node...
@ GET_ROUNDING
Returns current rounding mode: -1 Undefined 0 Round to 0 1 Round to nearest, ties to even 2 Round to ...
@ MULHU
MULHU/MULHS - Multiply high - Multiply two integers of type iN, producing an unsigned/signed value of...
@ SHL
Shift and rotation operations.
@ VECTOR_SHUFFLE
VECTOR_SHUFFLE(VEC1, VEC2) - Returns a vector, of the same type as VEC1/VEC2.
@ EXTRACT_SUBVECTOR
EXTRACT_SUBVECTOR(VECTOR, IDX) - Returns a subvector from VECTOR.
@ FMINNUM_IEEE
FMINNUM_IEEE/FMAXNUM_IEEE - Perform floating-point minimum or maximum on two values,...
@ EXTRACT_VECTOR_ELT
EXTRACT_VECTOR_ELT(VECTOR, IDX) - Returns a single element from VECTOR identified by the (potentially...
@ ZERO_EXTEND
ZERO_EXTEND - Used for integer types, zeroing the new bits.
@ SELECT_CC
Select with condition operator - This selects between a true value and a false value (ops #2 and #3) ...
@ ATOMIC_CMP_SWAP
Val, OUTCHAIN = ATOMIC_CMP_SWAP(INCHAIN, ptr, cmp, swap) For double-word atomic operations: ValLo,...
@ FMINNUM
FMINNUM/FMAXNUM - Perform floating-point minimum or maximum on two values.
@ DYNAMIC_STACKALLOC
DYNAMIC_STACKALLOC - Allocate some number of bytes on the stack aligned to a specified boundary.
@ SIGN_EXTEND_INREG
SIGN_EXTEND_INREG - This operator atomically performs a SHL/SRA pair to sign extend a small value in ...
@ SMIN
[US]{MIN/MAX} - Binary minimum or maximum of signed or unsigned integers.
@ FP_EXTEND
X = FP_EXTEND(Y) - Extend a smaller FP type into a larger FP type.
@ VSELECT
Select with a vector condition (op #0) and two vector operands (ops #1 and #2), returning a vector re...
@ STRICT_SINT_TO_FP
STRICT_[US]INT_TO_FP - Convert a signed or unsigned integer to a floating point value.
@ INLINEASM_BR
INLINEASM_BR - Branching version of inline asm. Used by asm-goto.
@ EH_DWARF_CFA
EH_DWARF_CFA - This node represents the pointer to the DWARF Canonical Frame Address (CFA),...
@ FRAMEADDR
FRAMEADDR, RETURNADDR - These nodes represent llvm.frameaddress and llvm.returnaddress on the DAG.
@ STRICT_FP_ROUND
X = STRICT_FP_ROUND(Y, TRUNC) - Rounding 'Y' from a larger floating point type down to the precision ...
@ STRICT_FP_TO_SINT
STRICT_FP_TO_[US]INT - Convert a floating point value to a signed or unsigned integer.
@ FP_TO_SINT
FP_TO_[US]INT - Convert a floating point value to a signed or unsigned integer.
@ READCYCLECOUNTER
READCYCLECOUNTER - This corresponds to the readcyclecounter intrinsic.
@ STRICT_FP_EXTEND
X = STRICT_FP_EXTEND(Y) - Extend a smaller FP type into a larger FP type.
@ AND
Bitwise operators - logical and, logical or, logical xor.
@ TRAP
TRAP - Trapping instruction.
@ INTRINSIC_WO_CHAIN
RESULT = INTRINSIC_WO_CHAIN(INTRINSICID, arg1, arg2, ...) This node represents a target intrinsic fun...
@ ADDE
Carry-using nodes for multiple precision addition and subtraction.
@ STRICT_FADD
Constrained versions of the binary floating point operators.
@ INSERT_VECTOR_ELT
INSERT_VECTOR_ELT(VECTOR, VAL, IDX) - Returns VECTOR with the element at IDX replaced with VAL.
@ TokenFactor
TokenFactor - This node takes multiple tokens as input and produces a single token result.
@ FP_ROUND
X = FP_ROUND(Y, TRUNC) - Rounding 'Y' from a larger floating point type down to the precision of the ...
@ INLINEASM
INLINEASM - Represents an inline asm block.
@ EH_SJLJ_SETJMP
RESULT, OUTCHAIN = EH_SJLJ_SETJMP(INCHAIN, buffer) This corresponds to the eh.sjlj....
@ TRUNCATE
TRUNCATE - Completely drop the high bits.
@ VAARG
VAARG - VAARG has four operands: an input chain, a pointer, a SRCVALUE, and the alignment.
@ BRCOND
BRCOND - Conditional branch.
@ SHL_PARTS
SHL_PARTS/SRA_PARTS/SRL_PARTS - These operators are used for expanded integer shift operations.
@ AssertSext
AssertSext, AssertZext - These nodes record if a register contains a value that has already been zero...
@ FCOPYSIGN
FCOPYSIGN(X, Y) - Return the value of X with the sign of Y.
@ SADDSAT
RESULT = [US]ADDSAT(LHS, RHS) - Perform saturation addition on 2 integers with the same bit width (W)...
@ CALLSEQ_START
CALLSEQ_START/CALLSEQ_END - These operators mark the beginning and end of a call sequence,...
@ GET_DYNAMIC_AREA_OFFSET
GET_DYNAMIC_AREA_OFFSET - get offset from native SP to the address of the most recent dynamic alloca.
@ ADJUST_TRAMPOLINE
ADJUST_TRAMPOLINE - This corresponds to the adjust_trampoline intrinsic.
@ INTRINSIC_W_CHAIN
RESULT,OUTCHAIN = INTRINSIC_W_CHAIN(INCHAIN, INTRINSICID, arg1, ...) This node represents a target in...
@ BUILD_VECTOR
BUILD_VECTOR(ELT0, ELT1, ELT2, ELT3,...) - Return a fixed-width vector with the specified,...
bool isNormalStore(const SDNode *N)
Returns true if the specified node is a non-truncating and unindexed store.
bool isZEXTLoad(const SDNode *N)
Returns true if the specified node is a ZEXTLOAD.
bool isUNINDEXEDLoad(const SDNode *N)
Returns true if the specified node is an unindexed load.
bool isEXTLoad(const SDNode *N)
Returns true if the specified node is a EXTLOAD.
bool isBuildVectorAllZeros(const SDNode *N)
Return true if the specified node is a BUILD_VECTOR where all of the elements are 0 or undef.
bool isSignedIntSetCC(CondCode Code)
Return true if this is a setcc instruction that performs a signed comparison when used with integer o...
MemIndexedMode
MemIndexedMode enum - This enum defines the load / store indexed addressing modes.
bool isSEXTLoad(const SDNode *N)
Returns true if the specified node is a SEXTLOAD.
CondCode
ISD::CondCode enum - These are ordered carefully to make the bitfields below work out,...
LoadExtType
LoadExtType enum - This enum defines the three variants of LOADEXT (load with extension).
bool isUnsignedIntSetCC(CondCode Code)
Return true if this is a setcc instruction that performs an unsigned comparison when used with intege...
bool isNormalLoad(const SDNode *N)
Returns true if the specified node is a non-extending and unindexed load.
Function * getDeclaration(Module *M, ID id, ArrayRef< Type * > Tys=std::nullopt)
Create or insert an LLVM Function declaration for an intrinsic, and return it.
@ Bitcast
Perform the operation on a different, but equivalently sized type.
@ MO_PIC_LO_FLAG
MO_PIC_LO_FLAG = MO_PIC_FLAG | MO_LO.
@ MO_TPREL_PCREL_FLAG
MO_TPREL_PCREL_FLAG = MO_PCREL_FLAG | MO_TPREL_FLAG.
@ MO_GOT_TPREL_PCREL_FLAG
MO_GOT_TPREL_PCREL_FLAG - A combintaion of flags, if these bits are set they should produce the reloc...
@ MO_GOT_PCREL_FLAG
MO_GOT_PCREL_FLAG = MO_PCREL_FLAG | MO_GOT_FLAG.
@ MO_TLSGDM_FLAG
MO_TLSGDM_FLAG - If this bit is set the symbol reference is relative to the region handle of TLS Gene...
@ MO_PCREL_FLAG
MO_PCREL_FLAG - If this bit is set, the symbol reference is relative to the current instruction addre...
@ MO_TLS_PCREL_FLAG
MO_TPREL_PCREL_FLAG = MO_PCREL_FLAG | MO_TLS.
@ MO_PLT
On PPC, the 12 bits are not enough for all target operand flags.
@ MO_TLS
Symbol for VK_PPC_TLS fixup attached to an ADD instruction.
@ MO_TPREL_FLAG
MO_TPREL_FLAG - If this bit is set, the symbol reference is relative to the thread pointer and the sy...
@ MO_LO
MO_LO, MO_HA - lo16(symbol) and ha16(symbol)
@ MO_GOT_TLSLD_PCREL_FLAG
MO_GOT_TLSLD_PCREL_FLAG - A combintaion of flags, if these bits are set they should produce the reloc...
@ MO_PIC_HA_FLAG
MO_PIC_HA_FLAG = MO_PIC_FLAG | MO_HA.
@ MO_TLSGD_FLAG
MO_TLSGD_FLAG - If this bit is set the symbol reference is relative to TLS General Dynamic model for ...
@ MO_GOT_TLSGD_PCREL_FLAG
MO_GOT_TLSGD_PCREL_FLAG - A combintaion of flags, if these bits are set they should produce the reloc...
@ MO_PIC_FLAG
MO_PIC_FLAG - If this bit is set, the symbol reference is relative to the function's picbase,...
@ SEXT_LD_SPLAT
VSRC, CHAIN = SEXT_LD_SPLAT, CHAIN, Ptr - a splatting load memory that sign-extends.
@ FCTIDUZ
Newer FCTI[D,W]UZ floating-point-to-integer conversion instructions for unsigned integers with round ...
@ ADDI_TLSGD_L_ADDR
G8RC = ADDI_TLSGD_L_ADDR G8RReg, Symbol, Symbol - Op that combines ADDI_TLSGD_L and GET_TLS_ADDR unti...
@ FSQRT
Square root instruction.
@ STRICT_FCFID
Constrained integer-to-floating-point conversion instructions.
@ DYNALLOC
The following two target-specific nodes are used for calls through function pointers in the 64-bit SV...
@ COND_BRANCH
CHAIN = COND_BRANCH CHAIN, CRRC, OPC, DESTBB [, INFLAG] - This corresponds to the COND_BRANCH pseudo ...
@ CALL_RM
The variants that implicitly define rounding mode for calls with strictfp semantics.
@ STORE_VEC_BE
CHAIN = STORE_VEC_BE CHAIN, VSRC, Ptr - Occurs only for little endian.
@ BDNZ
CHAIN = BDNZ CHAIN, DESTBB - These are used to create counter-based loops.
@ MTVSRZ
Direct move from a GPR to a VSX register (zero)
@ SRL
These nodes represent PPC shifts.
@ VECINSERT
VECINSERT - The PPC vector insert instruction.
@ LXSIZX
GPRC, CHAIN = LXSIZX, CHAIN, Ptr, ByteWidth - This is a load of an integer smaller than 64 bits into ...
@ FNMSUB
FNMSUB - Negated multiply-subtract instruction.
@ RFEBB
CHAIN = RFEBB CHAIN, State - Return from event-based branch.
@ FCTIDZ
FCTI[D,W]Z - The FCTIDZ and FCTIWZ instructions, taking an f32 or f64 operand, producing an f64 value...
@ SC
CHAIN = SC CHAIN, Imm128 - System call.
@ GET_TLS_ADDR
x3 = GET_TLS_ADDR x3, Symbol - For the general-dynamic TLS model, produces a call to __tls_get_addr(s...
@ XXSPLTI32DX
XXSPLTI32DX - The PPC XXSPLTI32DX instruction.
@ ANDI_rec_1_EQ_BIT
i1 = ANDI_rec_1_[EQ|GT]_BIT(i32 or i64 x) - Represents the result of the eq or gt bit of CR0 after ex...
@ FRE
Reciprocal estimate instructions (unary FP ops).
@ ADDIS_GOT_TPREL_HA
G8RC = ADDIS_GOT_TPREL_HA x2, Symbol - Used by the initial-exec TLS model, produces an ADDIS8 instruc...
@ CLRBHRB
CHAIN = CLRBHRB CHAIN - Clear branch history rolling buffer.
@ STORE_COND
CHAIN,Glue = STORE_COND CHAIN, GPR, Ptr The store conditional instruction ST[BHWD]ARX that produces a...
@ SINT_VEC_TO_FP
Extract a subvector from signed integer vector and convert to FP.
@ EXTRACT_SPE
Extract SPE register component, second argument is high or low.
@ XXSWAPD
VSRC, CHAIN = XXSWAPD CHAIN, VSRC - Occurs only for little endian.
@ ADDI_TLSLD_L_ADDR
G8RC = ADDI_TLSLD_L_ADDR G8RReg, Symbol, Symbol - Op that combines ADDI_TLSLD_L and GET_TLSLD_ADDR un...
@ ATOMIC_CMP_SWAP_8
ATOMIC_CMP_SWAP - the exact same as the target-independent nodes except they ensure that the compare ...
@ ST_VSR_SCAL_INT
Store scalar integers from VSR.
@ VCMP
RESVEC = VCMP(LHS, RHS, OPC) - Represents one of the altivec VCMP* instructions.
@ BCTRL
CHAIN,FLAG = BCTRL(CHAIN, INFLAG) - Directly corresponds to a BCTRL instruction.
@ BUILD_SPE64
BUILD_SPE64 and EXTRACT_SPE are analogous to BUILD_PAIR and EXTRACT_ELEMENT but take f64 arguments in...
@ LFIWZX
GPRC, CHAIN = LFIWZX CHAIN, Ptr - This is a floating-point load which zero-extends from a 32-bit inte...
@ RET_GLUE
Return with a glue operand, matched by 'blr'.
@ SCALAR_TO_VECTOR_PERMUTED
PowerPC instructions that have SCALAR_TO_VECTOR semantics tend to place the value into the least sign...
@ EXTRACT_VSX_REG
EXTRACT_VSX_REG = Extract one of the underlying vsx registers of an accumulator or pair register.
@ STXSIX
STXSIX - The STXSI[bh]X instruction.
@ MAT_PCREL_ADDR
MAT_PCREL_ADDR = Materialize a PC Relative address.
@ MFOCRF
R32 = MFOCRF(CRREG, INFLAG) - Represents the MFOCRF instruction.
@ XXSPLT
XXSPLT - The PPC VSX splat instructions.
@ TOC_ENTRY
GPRC = TOC_ENTRY GA, TOC Loads the entry for GA from the TOC, where the TOC base is given by the last...
@ XXPERMDI
XXPERMDI - The PPC XXPERMDI instruction.
@ ADDIS_DTPREL_HA
G8RC = ADDIS_DTPREL_HA x3, Symbol - For the local-dynamic TLS model, produces an ADDIS8 instruction t...
@ ADD_TLS
G8RC = ADD_TLS G8RReg, Symbol - Can be used by the initial-exec and local-exec TLS models,...
@ MTVSRA
Direct move from a GPR to a VSX register (algebraic)
@ VADD_SPLAT
VRRC = VADD_SPLAT Elt, EltSize - Temporary node to be expanded during instruction selection to optimi...
@ PPC32_GOT
GPRC = address of GLOBAL_OFFSET_TABLE.
@ ADDI_DTPREL_L
G8RC = ADDI_DTPREL_L G8RReg, Symbol - For the local-dynamic TLS model, produces an ADDI8 instruction ...
@ BCTRL_LOAD_TOC
CHAIN,FLAG = BCTRL(CHAIN, ADDR, INFLAG) - The combination of a bctrl instruction and the TOC reload r...
@ PPC32_PICGOT
GPRC = address of GLOBAL_OFFSET_TABLE.
@ FCFID
FCFID - The FCFID instruction, taking an f64 operand and producing and f64 value containing the FP re...
@ CR6SET
ch, gl = CR6[UN]SET ch, inglue - Toggle CR bit 6 for SVR4 vararg calls
@ LBRX
GPRC, CHAIN = LBRX CHAIN, Ptr, Type - This is a byte-swapping load instruction.
@ LD_VSX_LH
VSRC, CHAIN = LD_VSX_LH CHAIN, Ptr - This is a floating-point load of a v2f32 value into the lower ha...
@ PROBED_ALLOCA
To avoid stack clash, allocation is performed by block and each block is probed.
@ XXMFACC
XXMFACC = This corresponds to the xxmfacc instruction.
@ ADDIS_TLSGD_HA
G8RC = ADDIS_TLSGD_HA x2, Symbol - For the general-dynamic TLS model, produces an ADDIS8 instruction ...
@ ACC_BUILD
ACC_BUILD = Build an accumulator register from 4 VSX registers.
@ GlobalBaseReg
The result of the mflr at function entry, used for PIC code.
@ LXVD2X
VSRC, CHAIN = LXVD2X_LE CHAIN, Ptr - Occurs only for little endian.
@ XSMAXC
XSMAXC[DQ]P, XSMINC[DQ]P - C-type min/max instructions.
@ CALL
CALL - A direct function call.
@ MTCTR
CHAIN,FLAG = MTCTR(VAL, CHAIN[, INFLAG]) - Directly corresponds to a MTCTR instruction.
@ TC_RETURN
TC_RETURN - A tail call return.
@ STFIWX
STFIWX - The STFIWX instruction.
@ LD_SPLAT
VSRC, CHAIN = LD_SPLAT, CHAIN, Ptr - a splatting load memory instructions such as LXVDSX,...
@ VCMP_rec
RESVEC, OUTFLAG = VCMP_rec(LHS, RHS, OPC) - Represents one of the altivec VCMP*_rec instructions.
@ MFFS
F8RC = MFFS - This moves the FPSCR (not modeled) into the register.
@ PADDI_DTPREL
G8RC = PADDI_DTPREL x3, Symbol - For the pc-rel based local-dynamic TLS model, produces a PADDI8 inst...
@ BUILD_FP128
Direct move of 2 consecutive GPR to a VSX register.
@ VEXTS
VEXTS, ByteWidth - takes an input in VSFRC and produces an output in VSFRC that is sign-extended from...
@ TLS_LOCAL_EXEC_MAT_ADDR
TLS_LOCAL_EXEC_MAT_ADDR = Materialize an address for TLS global address when using local exec access ...
@ VPERM
VPERM - The PPC VPERM Instruction.
@ ADDIS_TLSLD_HA
G8RC = ADDIS_TLSLD_HA x2, Symbol - For the local-dynamic TLS model, produces an ADDIS8 instruction th...
@ XXSPLTI_SP_TO_DP
XXSPLTI_SP_TO_DP - The PPC VSX splat instructions for immediates for converting immediate single prec...
@ GET_TLSLD_ADDR
x3 = GET_TLSLD_ADDR x3, Symbol - For the local-dynamic TLS model, produces a call to __tls_get_addr(s...
@ ADDI_TLSGD_L
x3 = ADDI_TLSGD_L G8RReg, Symbol - For the general-dynamic TLS model, produces an ADDI8 instruction t...
@ DYNAREAOFFSET
This instruction is lowered in PPCRegisterInfo::eliminateFrameIndex to compute an offset from native ...
@ PAIR_BUILD
PAIR_BUILD = Build a vector pair register from 2 VSX registers.
@ STRICT_FADDRTZ
Constrained floating point add in round-to-zero mode.
@ FTSQRT
Test instruction for software square root.
@ FP_EXTEND_HALF
FP_EXTEND_HALF(VECTOR, IDX) - Custom extend upper (IDX=0) half or lower (IDX=1) half of v4f32 to v2f6...
@ CMPB
The CMPB instruction (takes two operands of i32 or i64).
@ VECSHL
VECSHL - The PPC vector shift left instruction.
@ ADDI_TLSLD_L
x3 = ADDI_TLSLD_L G8RReg, Symbol - For the local-dynamic TLS model, produces an ADDI8 instruction tha...
@ FADDRTZ
F8RC = FADDRTZ F8RC, F8RC - This is an FADD done with rounding towards zero.
@ ZEXT_LD_SPLAT
VSRC, CHAIN = ZEXT_LD_SPLAT, CHAIN, Ptr - a splatting load memory that zero-extends.
@ SRA_ADDZE
The combination of sra[wd]i and addze used to implemented signed integer division by a power of 2.
@ EXTSWSLI
EXTSWSLI = The PPC extswsli instruction, which does an extend-sign word and shift left immediate.
@ STXVD2X
CHAIN = STXVD2X CHAIN, VSRC, Ptr - Occurs only for little endian.
@ TLSGD_AIX
GPRC = TLSGD_AIX, TOC_ENTRY, TOC_ENTRY G8RC = TLSGD_AIX, TOC_ENTRY, TOC_ENTRY Op that combines two re...
@ UINT_VEC_TO_FP
Extract a subvector from unsigned integer vector and convert to FP.
@ GET_TPOINTER
x3 = GET_TPOINTER - Used for the local- and initial-exec TLS model on 32-bit AIX, produces a call to ...
@ LXVRZX
LXVRZX - Load VSX Vector Rightmost and Zero Extend This node represents v1i128 BUILD_VECTOR of a zero...
@ MFBHRBE
GPRC, CHAIN = MFBHRBE CHAIN, Entry, Dummy - Move from branch history rolling buffer entry.
@ FCFIDU
Newer FCFID[US] integer-to-floating-point conversion instructions for unsigned integers and single-pr...
@ FSEL
FSEL - Traditional three-operand fsel node.
@ SWAP_NO_CHAIN
An SDNode for swaps that are not associated with any loads/stores and thereby have no chain.
@ LOAD_VEC_BE
VSRC, CHAIN = LOAD_VEC_BE CHAIN, Ptr - Occurs only for little endian.
@ LFIWAX
GPRC, CHAIN = LFIWAX CHAIN, Ptr - This is a floating-point load which sign-extends from a 32-bit inte...
@ STBRX
CHAIN = STBRX CHAIN, GPRC, Ptr, Type - This is a byte-swapping store instruction.
@ LD_GOT_TPREL_L
G8RC = LD_GOT_TPREL_L Symbol, G8RReg - Used by the initial-exec TLS model, produces a LD instruction ...
@ MFVSR
Direct move from a VSX register to a GPR.
@ TLS_DYNAMIC_MAT_PCREL_ADDR
TLS_DYNAMIC_MAT_PCREL_ADDR = Materialize a PC Relative address for TLS global address when using dyna...
@ Hi
Hi/Lo - These represent the high and low 16-bit parts of a global address respectively.
Predicate
Predicate - These are "(BI << 5) | BO" for various predicates.
SDValue get_VSPLTI_elt(SDNode *N, unsigned ByteSize, SelectionDAG &DAG)
get_VSPLTI_elt - If this is a build_vector of constants which can be formed by using a vspltis[bhw] i...
bool isXXBRDShuffleMask(ShuffleVectorSDNode *N)
isXXBRDShuffleMask - Return true if this is a shuffle mask suitable for a XXBRD instruction.
FastISel * createFastISel(FunctionLoweringInfo &FuncInfo, const TargetLibraryInfo *LibInfo)
bool isVMRGHShuffleMask(ShuffleVectorSDNode *N, unsigned UnitSize, unsigned ShuffleKind, SelectionDAG &DAG)
isVMRGHShuffleMask - Return true if this is a shuffle mask suitable for a VRGH* instruction with the ...
bool isVPKUDUMShuffleMask(ShuffleVectorSDNode *N, unsigned ShuffleKind, SelectionDAG &DAG)
isVPKUDUMShuffleMask - Return true if this is the shuffle mask for a VPKUDUM instruction.
bool isVMRGEOShuffleMask(ShuffleVectorSDNode *N, bool CheckEven, unsigned ShuffleKind, SelectionDAG &DAG)
isVMRGEOShuffleMask - Return true if this is a shuffle mask suitable for a VMRGEW or VMRGOW instructi...
bool isXXBRQShuffleMask(ShuffleVectorSDNode *N)
isXXBRQShuffleMask - Return true if this is a shuffle mask suitable for a XXBRQ instruction.
bool isXXBRWShuffleMask(ShuffleVectorSDNode *N)
isXXBRWShuffleMask - Return true if this is a shuffle mask suitable for a XXBRW instruction.
bool isXXPERMDIShuffleMask(ShuffleVectorSDNode *N, unsigned &ShiftElts, bool &Swap, bool IsLE)
isXXPERMDIShuffleMask - Return true if this is a shuffle mask suitable for a XXPERMDI instruction.
bool isXXBRHShuffleMask(ShuffleVectorSDNode *N)
isXXBRHShuffleMask - Return true if this is a shuffle mask suitable for a XXBRH instruction.
unsigned getSplatIdxForPPCMnemonics(SDNode *N, unsigned EltSize, SelectionDAG &DAG)
getSplatIdxForPPCMnemonics - Return the splat index as a value that is appropriate for PPC mnemonics ...
bool isXXSLDWIShuffleMask(ShuffleVectorSDNode *N, unsigned &ShiftElts, bool &Swap, bool IsLE)
isXXSLDWIShuffleMask - Return true if this is a shuffle mask suitable for a XXSLDWI instruction.
int isVSLDOIShuffleMask(SDNode *N, unsigned ShuffleKind, SelectionDAG &DAG)
isVSLDOIShuffleMask - If this is a vsldoi shuffle mask, return the shift amount, otherwise return -1.
bool isVMRGLShuffleMask(ShuffleVectorSDNode *N, unsigned UnitSize, unsigned ShuffleKind, SelectionDAG &DAG)
isVMRGLShuffleMask - Return true if this is a shuffle mask suitable for a VRGL* instruction with the ...
bool isXXINSERTWMask(ShuffleVectorSDNode *N, unsigned &ShiftElts, unsigned &InsertAtByte, bool &Swap, bool IsLE)
isXXINSERTWMask - Return true if this VECTOR_SHUFFLE can be handled by the XXINSERTW instruction intr...
bool isSplatShuffleMask(ShuffleVectorSDNode *N, unsigned EltSize)
isSplatShuffleMask - Return true if the specified VECTOR_SHUFFLE operand specifies a splat of a singl...
bool isVPKUWUMShuffleMask(ShuffleVectorSDNode *N, unsigned ShuffleKind, SelectionDAG &DAG)
isVPKUWUMShuffleMask - Return true if this is the shuffle mask for a VPKUWUM instruction.
bool isVPKUHUMShuffleMask(ShuffleVectorSDNode *N, unsigned ShuffleKind, SelectionDAG &DAG)
isVPKUHUMShuffleMask - Return true if this is the shuffle mask for a VPKUHUM instruction.
Libcall
RTLIB::Libcall enum - This enum defines all of the runtime library calls the backend can emit.
@ Define
Register definition.
Reg
All possible values of the reg field in the ModR/M byte.
@ XTY_ER
External reference.
initializer< Ty > init(const Ty &Val)
const_iterator end(StringRef path)
Get end iterator over path.
This is an optimization pass for GlobalISel generic memory operations.
static bool isIndirectCall(const MachineInstr &MI)
bool all_of(R &&range, UnaryPredicate P)
Provide wrappers to std::all_of which take ranges instead of having to pass begin/end explicitly.
bool checkConvertToNonDenormSingle(APFloat &ArgAPFloat)
void GetReturnInfo(CallingConv::ID CC, Type *ReturnType, AttributeList attr, SmallVectorImpl< ISD::OutputArg > &Outs, const TargetLowering &TLI, const DataLayout &DL)
Given an LLVM IR type and return type attributes, compute the return value EVTs and flags,...
MachineInstrBuilder BuildMI(MachineFunction &MF, const MIMetadata &MIMD, const MCInstrDesc &MCID)
Builder interface. Specify how to create the initial instruction itself.
bool isNullConstant(SDValue V)
Returns true if V is a constant integer zero.
SDValue peekThroughBitcasts(SDValue V)
Return the non-bitcasted source operand of V if it exists.
bool CC_PPC32_SVR4_ByVal(unsigned ValNo, MVT ValVT, MVT LocVT, CCValAssign::LocInfo LocInfo, ISD::ArgFlagsTy ArgFlags, CCState &State)
bool isAligned(Align Lhs, uint64_t SizeInBytes)
Checks that SizeInBytes is a multiple of the alignment.
bool isIntS16Immediate(SDNode *N, int16_t &Imm)
isIntS16Immediate - This method tests to see if the node is either a 32-bit or 64-bit immediate,...
bool CC_PPC32_SVR4_VarArg(unsigned ValNo, MVT ValVT, MVT LocVT, CCValAssign::LocInfo LocInfo, ISD::ArgFlagsTy ArgFlags, CCState &State)
constexpr bool isPowerOf2_64(uint64_t Value)
Return true if the argument is a power of two > 0 (64 bit edition.)
int countr_zero(T Val)
Count number of 0's from the least significant bit to the most stopping at the first 1.
unsigned M1(unsigned Val)
bool isReleaseOrStronger(AtomicOrdering AO)
bool any_of(R &&range, UnaryPredicate P)
Provide wrappers to std::any_of which take ranges instead of having to pass begin/end explicitly.
bool RetCC_PPC_Cold(unsigned ValNo, MVT ValVT, MVT LocVT, CCValAssign::LocInfo LocInfo, ISD::ArgFlagsTy ArgFlags, CCState &State)
constexpr bool isPowerOf2_32(uint32_t Value)
Return true if the argument is a power of two > 0.
bool convertToNonDenormSingle(APInt &ArgAPInt)
FPClassTest
Floating-point class tests, supported by 'is_fpclass' intrinsic.
bool CC_PPC32_SVR4(unsigned ValNo, MVT ValVT, MVT LocVT, CCValAssign::LocInfo LocInfo, ISD::ArgFlagsTy ArgFlags, CCState &State)
raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
void report_fatal_error(Error Err, bool gen_crash_diag=true)
Report a serious error, calling any installed error handler.
bool CC_PPC64_ELF(unsigned ValNo, MVT ValVT, MVT LocVT, CCValAssign::LocInfo LocInfo, ISD::ArgFlagsTy ArgFlags, CCState &State)
bool RetCC_PPC(unsigned ValNo, MVT ValVT, MVT LocVT, CCValAssign::LocInfo LocInfo, ISD::ArgFlagsTy ArgFlags, CCState &State)
raw_fd_ostream & errs()
This returns a reference to a raw_ostream for standard error.
AtomicOrdering
Atomic ordering for LLVM's memory model.
@ Mod
The access may modify the value stored in memory.
bool isIntS34Immediate(SDNode *N, int64_t &Imm)
isIntS34Immediate - This method tests if value of node given can be accurately represented as a sign ...
bool CCAssignFn(unsigned ValNo, MVT ValVT, MVT LocVT, CCValAssign::LocInfo LocInfo, ISD::ArgFlagsTy ArgFlags, CCState &State)
CCAssignFn - This function assigns a location for Val, updating State to reflect the change.
@ Mul
Product of integers.
uint64_t alignTo(uint64_t Size, Align A)
Returns a multiple of A needed to store Size bytes.
auto count(R &&Range, const E &Element)
Wrapper function around std::count to count the number of times an element Element occurs in the give...
DWARFExpression::Operation Op
unsigned M0(unsigned Val)
ConstantSDNode * isConstOrConstSplat(SDValue N, bool AllowUndefs=false, bool AllowTruncation=false)
Returns the SDNode if it is a constant splat BuildVector or constant int.
bool isAcquireOrStronger(AtomicOrdering AO)
constexpr int32_t SignExtend32(uint32_t X)
Sign-extend the number in the bottom B bits of X to a 32-bit integer.
constexpr unsigned BitWidth
Align commonAlignment(Align A, uint64_t Offset)
Returns the alignment that satisfies both alignments.
constexpr int64_t SignExtend64(uint64_t x)
Sign-extend the number in the bottom B bits of X to a 64-bit integer.
T bit_floor(T Value)
Returns the largest integral power of two no greater than Value if Value is nonzero.
bool isAllOnesConstant(SDValue V)
Returns true if V is an integer constant with all bits set.
void swap(llvm::BitVector &LHS, llvm::BitVector &RHS)
Implement std::swap in terms of BitVector swap.
This is used by foldLoadsRecursive() to capture a Root Load node which is of type or(load,...
static const fltSemantics & IEEEsingle() LLVM_READNONE
static constexpr roundingMode rmNearestTiesToEven
static const fltSemantics & PPCDoubleDouble() LLVM_READNONE
static constexpr roundingMode rmTowardZero
This struct is a compact representation of a valid (non-zero power of two) alignment.
uint64_t value() const
This is a hole in the type system and should not be abused.
Represent subnormal handling kind for floating point instruction inputs and outputs.
EVT changeVectorElementTypeToInteger() const
Return a vector with the same number of elements as this vector, but with the element type converted ...
TypeSize getStoreSize() const
Return the number of bytes overwritten by a store of the specified value type.
bool isSimple() const
Test if the given EVT is simple (as opposed to being extended).
static EVT getVectorVT(LLVMContext &Context, EVT VT, unsigned NumElements, bool IsScalable=false)
Returns the EVT that represents a vector NumElements in length, where each element is of type VT.
bool bitsGT(EVT VT) const
Return true if this has more bits than VT.
bool isFloatingPoint() const
Return true if this is a FP or a vector FP type.
TypeSize getSizeInBits() const
Return the size of the specified value type in bits.
uint64_t getScalarSizeInBits() const
MVT getSimpleVT() const
Return the SimpleValueType held in the specified simple EVT.
static EVT getIntegerVT(LLVMContext &Context, unsigned BitWidth)
Returns the EVT that represents an integer with the given number of bits.
uint64_t getFixedSizeInBits() const
Return the size of the specified fixed width value type in bits.
bool isVector() const
Return true if this is a vector value type.
EVT getScalarType() const
If this is a vector type, return the element type, otherwise return this.
Type * getTypeForEVT(LLVMContext &Context) const
This method returns an LLVM type corresponding to the specified EVT.
EVT getVectorElementType() const
Given a vector type, return the type of each element.
bool isExtended() const
Test if the given EVT is extended (as opposed to being simple).
bool isScalarInteger() const
Return true if this is an integer, but not a vector.
unsigned getVectorNumElements() const
Given a vector type, return the number of elements it contains.
EVT getHalfNumVectorElementsVT(LLVMContext &Context) const
bool isInteger() const
Return true if this is an integer or a vector integer type.
unsigned getByValSize() const
void setByValSize(unsigned S)
Align getNonZeroByValAlign() const
OutputArg - This struct carries flags and a value for a single outgoing (actual) argument or outgoing...
bool isConstant() const
Returns true if we know the value of all bits.
void resetAll()
Resets the known state of all bits.
const APInt & getConstant() const
Returns the value when all bits have a known value.
This class contains a discriminated union of information about pointers in memory operands,...
static MachinePointerInfo getStack(MachineFunction &MF, int64_t Offset, uint8_t ID=0)
Stack pointer relative access.
MachinePointerInfo getWithOffset(int64_t O) const
static MachinePointerInfo getGOT(MachineFunction &MF)
Return a MachinePointerInfo record that refers to a GOT entry.
static MachinePointerInfo getFixedStack(MachineFunction &MF, int FI, int64_t Offset=0)
Return a MachinePointerInfo record that refers to the specified FrameIndex.
This struct is a compact representation of a valid (power of two) or undefined (0) alignment.
Structure that collects some common arguments that get passed around between the functions for call l...
const CallingConv::ID CallConv
These are IR-level optimization flags that may be propagated to SDNodes.
This represents a list of ValueType's that has been intern'd by a SelectionDAG.
This represents an addressing mode of: BaseGV + BaseOffs + BaseReg + Scale*ScaleReg If BaseGV is null...
This contains information for each constraint that we are lowering.
This structure contains all information that is necessary for lowering calls.
CallLoweringInfo & setIsPostTypeLegalization(bool Value=true)
CallLoweringInfo & setLibCallee(CallingConv::ID CC, Type *ResultType, SDValue Target, ArgListTy &&ArgsList)
SmallVector< ISD::InputArg, 32 > Ins
CallLoweringInfo & setZExtResult(bool Value=true)
CallLoweringInfo & setDebugLoc(const SDLoc &dl)
CallLoweringInfo & setSExtResult(bool Value=true)
SmallVector< ISD::OutputArg, 32 > Outs
SmallVector< SDValue, 32 > OutVals
bool isBeforeLegalizeOps() const
bool isAfterLegalizeDAG() const
void AddToWorklist(SDNode *N)
bool isBeforeLegalize() const
SDValue CombineTo(SDNode *N, ArrayRef< SDValue > To, bool AddTo=true)